Aleph expone los datos de la red como una secuencia Manifold, que se puede transformar fácilmente en java.io.InputStream
, canal core.async, secuencia Clojure o muchas otras representaciones de bytes. Expone contenedores predeterminados simples para HTTP, TCP y UDP, pero permite el acceso al rendimiento completo y la flexibilidad de la biblioteca Netty subyacente.
Leiningen:
[aleph " 0.8.2 " ]
deps.edn:
aleph/aleph { :mvn/version " 0.8.2 " }
; ; alternatively
io.github.clj-commons/aleph { :git/sha " ... " }
Aleph sigue completamente las especificaciones de Ring y puede ser un reemplazo directo para cualquier servidor compatible con Ring existente. Sin embargo, también permite que la función del controlador devuelva un Manifold diferido para representar una respuesta final. Es posible que esta característica no funcione bien con el middleware Ring síncrono que modifica la respuesta, pero esto se puede solucionar fácilmente reimplementando el middleware utilizando el operador let-flow de Manifold. El asistente aleph.http/wrap-ring-async-handler
se puede utilizar para convertir el controlador de anillo asíncrono de 3 aridades en uno compatible con 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
El cuerpo de la respuesta también puede ser una secuencia Manifold, donde cada mensaje de la secuencia se envía como un fragmento, lo que permite un control preciso sobre las respuestas transmitidas para eventos enviados por el servidor y otros fines.
Para solicitudes de clientes HTTP, Aleph se modela a sí mismo después de clj-http, excepto que cada solicitud devuelve inmediatamente un Manifold diferido que representa la respuesta.
( 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 intenta imitar completamente la API y las capacidades de clj-http. Admite solicitudes de datos de formularios/multipartes, almacenes de cookies, servidores proxy y solicitudes de inspección con algunas diferencias notables:
La configuración de proxy debe establecerse para la conexión al configurar un grupo de conexiones; no se permiten configuraciones de proxy por solicitud.
La funcionalidad del proxy HTTP se amplía con configuraciones de túnel, encabezados HTTP opcionales y control de tiempo de espera de conexión; consulte todas las claves de configuración
:proxy-ignore-hosts
no es compatible
Tanto el middleware de cookies como el almacenamiento de cookies integrado no admiten parámetros de cookies obsoletos desde RFC2965: comentario, URL del comentario, descarte, versión (consulte la estructura completa de la cookie)
cuando se utiliza :debug
, :save-request?
y :debug-body?
opciones, las solicitudes correspondientes se almacenarían en :aleph/netty-request
, :aleph/request
, :aleph/request-body
claves del mapa de respuesta
:response-interceptor
no es compatible
Aleph presenta la configuración del grupo de conexiones :log-activity
para activar el registro de los cambios de estado de las conexiones, así como los volcados hexadecimales de solicitudes/respuestas.
Las opciones :cache
y :cache-config
no son compatibles por ahora
El cliente Aleph también admite resolución DNS totalmente asíncrona y altamente personalizable.
Para obtener más información, lea el código de ejemplo.
A partir de 0.7.0, Aleph admite HTTP/2 tanto en el cliente como en el servidor.
En su mayor parte, el soporte HTTP/2 de Aleph es un reemplazo directo para HTTP/1. Sin embargo, para compatibilidad con versiones anteriores, Aleph utiliza de forma predeterminada HTTP/1 únicamente. Consulte el código HTTP/2 de ejemplo para obtener una buena descripción general sobre cómo comenzar con HTTP/2.
Cosas a tener en cuenta:
pipeline-transform
para alterar el pipeline Netty subyacente, deberá verificar su uso para HTTP/2. Debajo del capó, el nuevo código HTTP/2 utiliza la configuración de canalización multiplexada de Netty, con una canalización compartida a nivel de conexión que alimenta marcos específicos de flujo a N canales creados para N flujos individuales. (Un par de solicitud/respuesta HTTP estándar se asigna a una única secuencia H2). En cualquier solicitud HTTP que tenga los encabezados Upgrade
adecuados, puede llamar a (aleph.http/websocket-connection req)
, que devuelve un diferido que genera una secuencia dúplex , que utiliza una secuencia única para representar la comunicación bidireccional. Los mensajes del cliente se pueden recibir vía take!
, y enviado al cliente vía put!
. Un controlador echo WebSocket, entonces, consistiría simplemente en:
( require '[manifold.stream :as s])
( defn echo-handler [req]
( let [s @( http/websocket-connection req)]
( s/connect s s)))
Esto toma todos los mensajes del cliente y los devuelve al socket dúplex, devolviéndolos al cliente. Los mensajes de texto de WebSocket se emitirán como cadenas y los mensajes binarios como matrices de bytes.
Los clientes WebSocket se pueden crear a través de (aleph.http/websocket-client url)
, que devuelve un diferido que genera una secuencia dúplex que puede enviar y recibir mensajes desde el servidor.
Para obtener más información, lea el código de ejemplo.
Un servidor TCP es similar a un servidor HTTP, excepto que para cada conexión el controlador toma dos argumentos: una secuencia dúplex y un mapa que contiene información sobre el cliente. La secuencia emitirá matrices de bytes, que se pueden convertir en otras representaciones de bytes utilizando la biblioteca de secuencias de bytes. La transmisión aceptará cualquier mensaje que pueda convertirse en una representación binaria.
Un servidor echo TCP es muy similar al ejemplo de WebSocket anterior:
( require '[aleph.tcp :as tcp])
( defn echo-handler [s info]
( s/connect s s))
( tcp/start-server echo-handler { :port 10001 })
Se puede crear un cliente TCP a través de (aleph.tcp/client {:host "example.com", :port 10001})
, que devuelve un diferido que produce una secuencia dúplex.
Para obtener más información, lea el código de ejemplo.
Se puede generar un socket UDP usando (aleph.udp/socket {:port 10001, :broadcast? false})
. Si se especifica :port
, generará un socket dúplex que se puede usar para enviar y recibir mensajes, que están estructurados como mapas con los siguientes datos:
{ :host " example.com "
:port 10001
:message ...}
Donde los paquetes entrantes tendrán un :message
que es una matriz de bytes, que se puede forzar mediante byte-streams
, y los paquetes salientes pueden ser cualquier dato que se pueda forzar a una representación binaria. Si no se especifica ningún :port
, el socket solo se puede utilizar para enviar mensajes.
Para obtener más información, lea el código de ejemplo.
Aleph utiliza Leiningen para gestionar dependencias, ejecutar REPL y pruebas, y crear el código.
La compatibilidad mínima con tools.deps
está disponible en forma de un archivo deps.edn
que se genera a partir de project.clj
. Proporciona lo suficiente para poder usar Aleph como una dependencia de git o :local/root
. Al confirmar cambios en project.clj
, ejecute deps/lein-to-deps
y confirme también los cambios resultantes.
Copyright © 2010-2024 Zachary Tellman
Distribuido bajo la licencia MIT.
Muchas gracias a YourKit por apoyar a Aleph. YourKit admite proyectos de código abierto con herramientas innovadoras e inteligentes para monitorear y crear perfiles de aplicaciones Java y .NET.
YourKit es el creador de YourKit Java Profiler, YourKit .NET Profiler y YourKit YouMonitor.