Aleph expose les données du réseau sous forme de flux Manifold, qui peut facilement être transformé en un canal java.io.InputStream
, core.async, une séquence Clojure ou de nombreuses autres représentations d'octets. Il expose de simples wrappers par défaut pour HTTP, TCP et UDP, mais permet d'accéder à toutes les performances et à la flexibilité de la bibliothèque Netty sous-jacente.
Leiningen :
[aleph " 0.8.2 " ]
deps.edn :
aleph/aleph { :mvn/version " 0.8.2 " }
; ; alternatively
io.github.clj-commons/aleph { :git/sha " ... " }
Aleph suit entièrement les spécifications Ring et peut remplacer tout serveur compatible Ring existant. Cependant, cela permet également à la fonction de gestionnaire de renvoyer un collecteur différé pour représenter une réponse éventuelle. Cette fonctionnalité peut ne pas fonctionner correctement avec le middleware Ring synchrone qui modifie la réponse, mais cela peut être facilement corrigé en réimplémentant le middleware à l'aide de l'opérateur let-flow de Manifold. L'assistant aleph.http/wrap-ring-async-handler
peut être utilisé pour convertir un gestionnaire Ring asynchrone à 3 arités en un gestionnaire compatible 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
Le corps de la réponse peut également être un flux collecteur, dans lequel chaque message du flux est envoyé sous forme de bloc, ce qui permet un contrôle précis des réponses diffusées en continu pour les événements envoyés par le serveur et à d'autres fins.
Pour les requêtes des clients HTTP, Aleph se modélise d'après clj-http, sauf que chaque requête renvoie immédiatement un collecteur différé représentant la réponse.
( 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 tente d'imiter pleinement l'API et les fonctionnalités clj-http. Il prend en charge les requêtes multipart/form-data, les magasins de cookies, les serveurs proxy et l'inspection des requêtes avec quelques différences notables :
la configuration du proxy doit être définie pour la connexion lors de la configuration d'un pool de connexions, les configurations de proxy par demande ne sont pas autorisées
La fonctionnalité du proxy HTTP est étendue avec des paramètres de tunneling, des en-têtes HTTP en option et un contrôle du délai d'expiration de la connexion. Voir toutes les clés de configuration.
:proxy-ignore-hosts
n'est pas pris en charge
le middleware des cookies et les stockages de cookies intégrés ne prennent pas en charge les paramètres de cookies obsolètes depuis la RFC2965 : commentaire, URL du commentaire, suppression, version (voir la structure complète du cookie)
lors de l'utilisation :debug
, :save-request?
et :debug-body?
options, les requêtes correspondantes seraient stockées dans les clés :aleph/netty-request
, :aleph/request
, :aleph/request-body
de la carte de réponse
L'option :response-interceptor
n'est pas prise en charge
Aleph introduit la configuration du pool de connexions :log-activity
pour activer la journalisation des changements d'état des connexions ainsi que les vidages hexadécimaux des demandes/réponses.
Les options :cache
et :cache-config
ne sont pas prises en charge pour l'instant
Le client Aleph prend également en charge un résolveur DNS entièrement asynchrone et hautement personnalisable.
Pour en savoir plus, lisez l’exemple de code.
Depuis la version 0.7.0, Aleph prend en charge HTTP/2 à la fois sur le client et sur le serveur.
Pour l'essentiel, la prise en charge HTTP/2 d'Aleph remplace HTTP/1. Cependant, pour des raisons de compatibilité ascendante, Aleph utilise par défaut HTTP/1 uniquement. Consultez l'exemple de code HTTP/2 pour un bon aperçu de la prise en main de HTTP/2.
Choses à prendre en compte :
pipeline-transform
pour modifier le pipeline Netty sous-jacent, vous devrez vérifier votre utilisation pour HTTP/2. Sous le capot, le nouveau code HTTP/2 utilise la configuration de pipeline multiplexé de Netty, avec un pipeline partagé au niveau de la connexion qui alimente les trames spécifiques au flux vers N pipelines créés pour N flux individuels. (Une paire requête/réponse HTTP standard correspond à un seul flux H2.) Sur toute requête HTTP comportant les en-têtes Upgrade
appropriés, vous pouvez appeler (aleph.http/websocket-connection req)
, qui renvoie un différé qui produit un flux duplex , qui utilise un seul flux pour représenter la communication bidirectionnelle. Les messages du client peuvent être reçus via take!
, et envoyé au client via put!
. Un gestionnaire echo WebSocket consisterait alors simplement en :
( require '[manifold.stream :as s])
( defn echo-handler [req]
( let [s @( http/websocket-connection req)]
( s/connect s s)))
Cela prend tous les messages du client et les renvoie dans le socket duplex, les renvoyant au client. Les messages texte WebSocket seront émis sous forme de chaînes et les messages binaires sous forme de tableaux d'octets.
Les clients WebSocket peuvent être créés via (aleph.http/websocket-client url)
, qui renvoie un différé qui génère un flux duplex pouvant envoyer et recevoir des messages du serveur.
Pour en savoir plus, lisez l’exemple de code.
Un serveur TCP est similaire à un serveur HTTP, sauf que pour chaque connexion le gestionnaire prend deux arguments : un flux duplex et une carte contenant des informations sur le client. Le flux émettra des tableaux d'octets, qui peuvent être contraints à d'autres représentations d'octets à l'aide de la bibliothèque byte-streams. Le flux acceptera tous les messages qui peuvent être convertis en une représentation binaire.
Un serveur echo TCP est très similaire à l'exemple WebSocket ci-dessus :
( require '[aleph.tcp :as tcp])
( defn echo-handler [s info]
( s/connect s s))
( tcp/start-server echo-handler { :port 10001 })
Un client TCP peut être créé via (aleph.tcp/client {:host "example.com", :port 10001})
, qui renvoie un différé qui produit un flux duplex.
Pour en savoir plus, lisez l’exemple de code.
Un socket UDP peut être généré en utilisant (aleph.udp/socket {:port 10001, :broadcast? false})
. Si le :port
est spécifié, il générera un socket duplex qui peut être utilisé pour envoyer et recevoir des messages, structurés sous forme de cartes avec les données suivantes :
{ :host " example.com "
:port 10001
:message ...}
Où les paquets entrants auront un :message
qui est un tableau d'octets, qui peut être forcé à l'aide de byte-streams
, et les paquets sortants peuvent être n'importe quelle donnée qui peut être contrainte à une représentation binaire. Si aucun :port
n'est spécifié, le socket ne peut être utilisé que pour envoyer des messages.
Pour en savoir plus, lisez l’exemple de code.
Aleph utilise Leiningen pour gérer les dépendances, exécuter des REPL et des tests et créer le code.
La prise en charge minimale tools.deps
est disponible sous la forme d'un fichier deps.edn
généré à partir de project.clj
. Il fournit juste assez pour pouvoir utiliser Aleph comme dépendance git ou :local/root
. Lorsque vous validez des modifications dans project.clj
, exécutez deps/lein-to-deps
et validez également les modifications résultantes.
Copyright © 2010-2024 Zachary Tellman
Distribué sous licence MIT.
Un grand merci à YourKit pour son soutien à Aleph. YourKit prend en charge les projets open source avec des outils innovants et intelligents pour surveiller et profiler les applications Java et .NET.
YourKit est le créateur de YourKit Java Profiler, YourKit .NET Profiler et YourKit YouMonitor.