RSocket is an application protocol for multiplexed duplex communication over TCP, WebSocket and other byte stream transfer mechanisms, using one of the following interaction models:

  • Request-Response – sending one message and receiving one in response.

  • Request-Stream – sending one message and receiving a stream of messages in response.

  • Channel – transmission of message streams in both directions.

  • Fire-and-Forget– sending a one-way message.

Once the initial connection is established, the distinction between "client" and "server" is lost as both sides become symmetrical and each side can initiate one of the above interactions. That is why in the protocol the participating parties are called “requester (requester)” and “responder (responder)”, and the above interactions are called “request flows” or simply “requests”.

These are the main features and advantages of the RSocket protocol:

  • Semantics of Reactive Streams at the network edge - for streaming requests such as Request-Stream and Channel, feedback signals pass between the requester and the responder, allowing the requester to slow down the responder at the source, reducing the dependence on congestion control at the network layer, as well as the need for buffering at the network layer or any another level.

  • Request Throttling - This feature is named "Leasing" after the LEASE frame that can be sent from either side to limit the total number of requests allowed by the other side in a given time . Restricted periods are periodically extended.

  • Session Resume - intended for cases of lost connection and requires saving a certain state. State management for applications is transparent and works well when combined with feedback, which can stop the provider when possible and reduce the amount of state required.

  • Fragmentation and reassembly of large messages.

  • Keepalive (heartbeat messages).

RSocket has implementations in several languages. Java library is built on top of Project Reactor, and Reactor Netty is used for transfer. This means that signals from Reactive Streams publishers in your application will be propagated transparently via RSocket across the network.

Protocol

One of the advantages of RSocket is that it has a clearly defined on-the-fly logic and a readable specification, as well as some extensions of the protocol. Therefore, it is wise to read the specification, regardless of the language implementation and higher-level framework APIs. This section provides a brief description of creating a specific context.

Connection

The client initially connects to the server via a low-level streaming media such as TCP or WebSocket and sends a SETUP frame to the server to set connection parameters.

The server may reject the SETUP frame, but usually after it is sent (for the client) and received (for the server) both sides can start sending requests unless SETUP specifies to use restricted-use semantics to limit the number of requests, in which case both sides must wait for a LEASE frame on the other side to allow requests to be made.

Executing queries

Once the connection is established, both parties can initiate a request through one of the REQUEST_RESPONSE, REQUEST_STREAM, REQUEST_CHANNEL or REQUEST_FNF frames . Each of these frames carries one message from the requester to the responder.

The responder may then return PAYLOAD frames with response messages, and in the case of REQUEST_CHANNEL the requester may also send PAYLOAD frames with additional request messages.

If the request includes a stream of messages, such as Request-Stream and Channel, the responder is required to follow the request signals from the requester. The request is expressed in the number of messages. The initial request is specified in the REQUEST_STREAM and REQUEST_CHANNEL frames. Subsequent requests are signaled using REQUEST_N frames.

Each side can also send metadata notifications through the METADATA_PUSH frame that are not specific to the individual request, but to the connection as a whole.

Message format

RSocket messages contain data and metadata. Metadata can be used to send a route, security token, etc. Data and metadata can be formatted in different ways. The MIME types for each are declared in the SETUP frame and apply to all requests for that connection.

Although all messages may contain metadata, typically metadata such as the route is provided with each request and is therefore included only in the first message of the request, that is, in one of the REQUEST_RESPONSE frames, REQUEST_STREAM, REQUEST_CHANNEL or REQUEST_FNF.

Protocol extensions define common metadata formats for use in applications:

Java implementation

The Java implementation for RSocket is built on top of Project Reactor. The transfer mechanisms for TCP and WebSocket are built on top of Reactor Netty. Being a Reactive Streams library, Reactor simplifies the work of implementing the protocol. In applications, it is natural to use Flux and Mono with declarative operators and transparent support for callback.

The RSocket API for Java is intentionally simplified and basic. It focuses on protocol specifics and preserving the application programming model (e.g., code generator for RPC versus others) as independent, higher-level functionality.

Main contract io.rsocket.RSocket models four types of request interactions, with Mono representing a single message promise, Flux representing a stream of messages, and io.rsocket.Payload – the message itself with access to data and metadata in the form of byte buffers. The RSocket contract is used symmetrically. In terms of sending requests, the application is provided with a RSocket to make requests. In terms of sending responses, the application implements RSocket to handle requests.

This description is not a comprehensive introduction. For the most part, Spring applications won't have to use its API directly. However, it may be important to see or experiment with RSocket separately from Spring. The Java repository for RSocket contains a number of sample applications demonstrating the API and protocol capabilities.

Spring Support Tools

The spring-messaging module contains the following:

  • RSocketRequester - a fluid API for making requests via io.rsocket.RSocket with data and metadata encoding/decoding.

  • Annotated responders are handler methods annotated with @MessageMapping for sending a response.

The spring-web module contains Encoder and Decoder implementations, such as Jackson CBOR/JSON and Protobuf, that applications are likely to need on RSocket. It also contains a PathPatternParser that can be hooked up for efficient route matching.

Spring Boot 2.2 supports creating an RSocket server over TCP or WebSocket, including the ability to use RSocket over WebSocket in a WebFlux server. There is also client support and auto-configuration for RSocketRequester.Builder and RSocketStrategies. For more information, see RSocket in the Spring Boot reference.

Spring Security 5.2 includes RSocket support.

Spring Integration 5.2 provides inbound and outbound gateways for interaction with RSocket clients and servers. For more information, see the Spring Integration Reference Manual.

Spring Cloud Gateway supports RSocket-based connections.