RSocket es un protocolo de aplicación para comunicación dúplex multiplexada a través de TCP, WebSocket y otros mecanismos de transferencia de flujo de bytes, utilizando uno de los siguientes modelos de interacción:

  • Request-Response: enviar un mensaje y recibir otro como respuesta.

  • Request-Stream: enviar un mensaje y recibir un flujo de mensajes en respuesta.

  • Channel: transmisión de flujos de mensajes en ambas direcciones.

  • Fire-and-Forget: envía un mensaje unidireccional.

Una vez establecida la conexión inicial, la distinción entre "cliente" y "servidor" se pierde ya que ambos lados se vuelven simétricos y cada lado puede iniciar una de las interacciones anteriores. Es por eso que en el protocolo las partes participantes se denominan “solicitante (solicitante)” y “respondedor (respondedor)”, y las interacciones anteriores se denominan “flujos de solicitud” o simplemente “solicitudes”.

Estas son las principales características y ventajas del protocolo RSocket:

  • Semántica de Reactive Streams en el borde de la red, para solicitudes de transmisión como Request-Stream y Channel, las señales de retroalimentación pasan entre el solicitante y el respondedor, lo que permite al solicitante ralentizar al respondedor en el origen, lo que también reduce la dependencia del control de congestión en la capa de red, como la necesidad de almacenamiento en búfer en la capa de red o en cualquier otro nivel.

  • Limitación de solicitudes: esta función se denomina "Arrendamiento" después del marco LEASE que se puede enviar desde cualquier lado para limitar el número total de solicitudes permitidas por el otro lado en un tiempo determinado. Los periodos restringidos se amplían periódicamente.

  • Reanudar sesión: destinado a casos de pérdida de conexión y requiere guardar un estado determinado. La gestión del estado de las aplicaciones es transparente y funciona bien cuando se combina con comentarios, que pueden detener al proveedor cuando sea posible y reducir la cantidad de estado requerido.

  • Fragmentación y reensamblaje de mensajes grandes.

  • Keepalive (mensajes de latidos del corazón).

RSocket tiene implementaciones en varios idiomas. La biblioteca Java está construida sobre Project Reactor, y Reactor Netty se utiliza para la transferencia. Esto significa que las señales de los editores de Reactive Streams en su aplicación se propagarán de forma transparente a través de RSocket en toda la red.

Protocolo

Una de las ventajas de RSocket es que tiene una lógica sobre la marcha claramente definida y una especificación legible, así como algunas extensiones del protocolo. Por lo tanto, es aconsejable leer la especificación, independientemente de la implementación del lenguaje y las API del marco de nivel superior. Esta sección proporciona una breve descripción de cómo crear un contexto específico.

Conexión

El cliente se conecta inicialmente al servidor a través de un medio de transmisión de bajo nivel como TCP o WebSocket y envía una trama SETUP al servidor para establecer los parámetros de conexión.

El servidor puede rechazar la trama SETUP, pero generalmente después de enviarla (para el cliente) y recibirla (para el servidor), ambas partes pueden comenzar a enviar solicitudes a menos que SETUP especifica el uso de semántica de uso restringido para limitar el número de solicitudes, en cuyo caso ambas partes deben esperar un marco LEASE en el otro lado para permitir que se realicen las solicitudes.

Ejecutando consultas

Una vez establecida la conexión, ambas partes pueden iniciar una solicitud a través de uno de los REQUEST_RESPONSE, REQUEST_STREAM, REQUEST_CHANNEL o REQUEST_FNF marcos. Cada una de estas tramas transporta un mensaje del solicitante al respondedor.

El respondedor puede entonces devolver marcos PAYLOAD con mensajes de respuesta y, en el caso de REQUEST_CHANNEL, el solicitante también puede enviar marcos PAYLOAD con mensajes de respuesta adicionales. solicitar mensajes.

Si la solicitud incluye un flujo de mensajes, como Request-Stream y Channel, el respondedor debe seguir las señales de solicitud del solicitante. La solicitud se expresa en el número de mensajes. La solicitud inicial se especifica en los marcos REQUEST_STREAM y REQUEST_CHANNEL. Las solicitudes posteriores se señalan mediante marcos REQUEST_N.

Cada parte también puede enviar notificaciones de metadatos a través del marco METADATA_PUSH que no son específicas de la solicitud individual, sino de la conexión en su conjunto.

Formato del mensaje

Los mensajes de RSocket contienen datos y metadatos. Los metadatos se pueden utilizar para enviar una ruta, un token de seguridad, etc. Los datos y metadatos se pueden formatear de diferentes maneras. Los tipos MIME para cada uno se declaran en el marco SETUP y se aplican a todas las solicitudes para esa conexión.

Aunque todos los mensajes pueden contener metadatos, normalmente metadatos como la ruta se proporcionan con cada solicitud y, por lo tanto, se incluyen solo en el primer mensaje de la solicitud, es decir, en uno de los marcos REQUEST_RESPONSE, REQUEST_STREAM, REQUEST_CHANNEL o REQUEST_FNF.

Las extensiones de protocolo definen formatos de metadatos comunes para su uso en aplicaciones:

Implementación de Java

La implementación de Java para RSocket está construida sobre Proyecto Reactor. Los mecanismos de transferencia para TCP y WebSocket se basan en Reactor Netty. Al ser una biblioteca Reactive Streams, Reactor simplifica el trabajo de implementación del protocolo. En las aplicaciones, es natural utilizar Flux y Mono con operadores declarativos y soporte transparente para devolución de llamada.

La API RSocket para Java está intencionalmente simplificada y es básica. Se centra en los detalles del protocolo y en preservar el modelo de programación de aplicaciones (por ejemplo, generador de código para RPC frente a otros) como una funcionalidad independiente de nivel superior.

Contrato principal io.rsocket.RSocket modela cuatro tipos de interacciones de solicitud: Mono representa una promesa de mensaje único, Flux representa un flujo de mensajes y io.rsocket.Payload: el mensaje en sí con acceso a datos y metadatos en forma de buffers de bytes. El contrato RSocket se utiliza simétricamente. En términos de envío de solicitudes, la aplicación cuenta con un RSocket para realizar solicitudes. En términos de envío de respuestas, la aplicación implementa RSocket para manejar las solicitudes.

Esta descripción no es una introducción completa. En su mayor parte, las aplicaciones Spring no tendrán que usar su API directamente. Sin embargo, puede ser importante ver o experimentar con RSocket por separado de Spring. El repositorio de Java para RSocket contiene una serie de aplicaciones de muestra que demuestran la Capacidades de protocolo y API.

Herramientas de soporte de Spring

El módulo spring-messaging contiene lo siguiente:

  • RSocketRequester: una API fluida para realizar solicitudes a través de io.rsocket.RSocket con codificación/decodificación de datos y metadatos.

  • Los respondedores anotados son métodos de controlador anotados con @MessageMapping para enviar una respuesta.

El módulo spring-web contiene implementaciones Encoder y Decoder, como Jackson CBOR/JSON y Protobuf, que las aplicaciones probablemente necesiten en RSocket. También contiene un PathPatternParser que se puede conectar para una coincidencia de rutas eficiente.

Spring Boot 2.2 admite la creación de un servidor RSocket sobre TCP o WebSocket, incluida la capacidad de usar RSocket sobre WebSocket en un servidor WebFlux. También hay soporte para clientes y configuración automática para RSocketRequester.Builder y RSocketStrategies. Para obtener más información, consulte RSocket en la referencia de Spring Boot.

Spring Security 5.2 incluye soporte para RSocket.

Spring Integration 5.2 proporciona puertas de enlace entrantes y salientes para interactuar con clientes y servidores RSocket. Para obtener más información, consulte el Manual de referencia de integración de Spring.

Spring Cloud Gateway admite conexiones basadas en RSocket.