Aleph 將來自網路的資料作為 Manifold 流公開,可以輕鬆轉換為java.io.InputStream
、 core.async 通道、 Clojure 序列或許多其他位元組表示形式。它公開了 HTTP、TCP 和 UDP 的簡單預設包裝器,但允許存取底層 Netty 庫的全部效能和靈活性。
萊寧根:
[aleph " 0.8.2 " ]
deps.edn:
aleph/aleph { :mvn/version " 0.8.2 " }
; ; alternatively
io.github.clj-commons/aleph { :git/sha " ... " }
Aleph 完全遵循 Ring 規範,並且可以直接取代任何現有的 Ring 相容伺服器。但是,它還允許處理程序函數返回延遲的 Manifold 以表示最終響應。此功能可能無法與修改回應的同步 Ring 中間件很好地配合,但可以透過使用 Manifold 的 let-flow 運算子重新實作中間件來輕鬆解決此問題。 aleph.http/wrap-ring-async-handler
幫助器可用於將非同步 3 元環處理程序轉換為符合 Aleph 的處理程序。
( require '[aleph.http :as http])
( defn handler [req]
{ :status 200
:headers { " content-type " " text/plain " }
:body " hello! " })
( http/start-server handler { :port 8080 }) ; HTTP/1-only
; ; To support HTTP/2, do the following:
; ; (def my-ssl-context ...)
( http/start-server handler { :port 443
:http-versions [ :http2 :http1 ]
:ssl-context my-ssl-context})
; ; See aleph.examples.http2 for more details
回應的主體也可以是一個 Manifold 流,其中流中的每個訊息都作為一個區塊發送,從而允許對伺服器發送事件和其他目的的串流回應進行精確控制。
對於 HTTP 用戶端請求,Aleph 依照 clj-http 進行建模,不同之處在於每個請求立即傳回代表回應的 Manifold deferred。
( require
'[aleph.http :as http]
'[manifold.deferred :as d]
'[clj-commons.byte-streams :as bs])
( -> @( http/get " https://google.com/ " )
:body
bs/to-string
prn)
( d/chain ( http/get " https://google.com " )
:body
bs/to-string
prn)
; ; To support HTTP/2, do the following:
( def conn-pool
( http/connection-pool { :connection-options { :http-versions [ :http2 :http1 ]}}))
@( http/get " https://google.com " { :pool conn-pool})
; ; See aleph.examples.http2 for more details
Aleph 嘗試完全模仿 clj-http API 和功能。它支援多部分/表單資料請求、cookie 儲存、代理伺服器和請求檢查,但有一些顯著差異:
設定連線池時應為連線設定代理配置,不允許依請求設定代理
HTTP 代理功能透過隧道設定、可選 HTTP 標頭和連接逾時控制進行了擴展,請參閱所有配置鍵
:proxy-ignore-hosts
cookie 中間件和內建 cookie 儲存都不支援自 RFC2965 以來已廢棄的 cookie 參數:comment、comment URL、discard、version(請參閱 cookie 的完整結構)
當使用:debug
、 :save-request?
和:debug-body?
選項,相應的請求將儲存在回應映射的:aleph/netty-request
、 :aleph/request
、 :aleph/request-body
鍵中
:response-interceptor
選項
Aleph 引入了:log-activity
連線池配置來開啟連線狀態變更以及請求/回應十六進位轉儲的日誌記錄
目前不支援:cache
和:cache-config
選項
Aleph 用戶端也支援完全非同步且高度可自訂的 DNS 解析器。
要了解更多信息,請閱讀範例程式碼。
從 0.7.0 開始,Aleph 在客戶端和伺服器中都支援 HTTP/2。
在大多數情況下,Aleph 的 HTTP/2 支援是 HTTP/1 的直接替代品。不過,為了向後相容,Aleph 預設僅使用 HTTP/1。有關 HTTP/2 入門的詳細概述,請參閱範例 HTTP/2 程式碼。
需要注意的事項:
pipeline-transform
來變更底層 Netty 管道,則需要檢查它對 HTTP/2 的使用情況。在底層,新的 HTTP/2 程式碼使用 Netty 的多路復用管道設置,以及一個共享連接級管道,該管道將特定於流的幀提供給為 N 個單獨流創建的 N 個管道。 (標準 HTTP 請求/回應對對應到單一 H2 流。)在任何具有正確Upgrade
標頭的 HTTP 請求中,您可以呼叫(aleph.http/websocket-connection req)
,它會傳回 deferred ,它會產生一個雙工流,它使用單一流來表示雙向通訊。可以透過take!
接收來自客戶端的訊息! ,並透過put!
發送給客戶端。那麼,一個 echo WebSocket 處理程序將只包含以下內容:
( require '[manifold.stream :as s])
( defn echo-handler [req]
( let [s @( http/websocket-connection req)]
( s/connect s s)))
這將從客戶端獲取所有訊息,並將它們反饋到雙工套接字中,然後將它們返回給客戶端。 WebSocket 文字訊息將以字串形式發出,二進位訊息以位元組數組形式發出。
WebSocket 用戶端可以透過(aleph.http/websocket-client url)
創建,它會傳回一個延遲,產生一個可以從伺服器發送和接收訊息的雙工流。
要了解更多信息,請閱讀範例程式碼。
TCP 伺服器與 HTTP 伺服器類似,不同之處在於,對於每個連接,處理程序採用兩個參數:一個雙工流和一個包含有關客戶端資訊的對應。此流將發出位元組數組,可以使用位元組流庫將其強制轉換為其他位元組表示形式。該流將接受任何可以強制轉換為二進位表示形式的訊息。
echo TCP 伺服器與上面的 WebSocket 範例非常相似:
( require '[aleph.tcp :as tcp])
( defn echo-handler [s info]
( s/connect s s))
( tcp/start-server echo-handler { :port 10001 })
TCP 用戶端可以透過(aleph.tcp/client {:host "example.com", :port 10001})
創建,它會傳回一個延遲,從而產生一個雙工流。
要了解更多信息,請閱讀範例程式碼。
可以使用(aleph.udp/socket {:port 10001, :broadcast? false})
來產生 UDP 套接字。如果指定了:port
,它將產生一個雙工套接字,可用於發送和接收訊息,訊息的結構為具有以下資料的對應:
{ :host " example.com "
:port 10001
:message ...}
其中傳入資料包將有一個:message
,它是一個位元組數組,可以使用byte-streams
進行強制,而傳出資料包可以是任何可以強制為二進位表示的資料。如果沒有指定:port
,則套接字只能用於傳送訊息。
要了解更多信息,請閱讀範例程式碼。
Aleph 使用 Leiningen 來管理相依性、執行 REPL 和測試以及建置程式碼。
最小的tools.deps
支援以deps.edn
檔案的形式提供,該檔案是從project.clj
產生的。它提供的功能足以將 Aleph 用作 git 或:local/root
依賴項。當提交對project.clj
的變更時,執行deps/lein-to-deps
並提交產生的變更。
版權所有 © 2010-2024 札卡里‧泰爾曼
根據 MIT 許可證分發。
非常感謝 YourKit 對 Aleph 的支持。 YourKit 透過創新和智慧的工具支援開源項目,用於監視和分析 Java 和 .NET 應用程式。
YourKit 是 YourKit Java Profiler、YourKit .NET Profiler 和 YourKit YouMonitor 的創作者。