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
andChannel
, 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:
-
Composite metadata – multiple independently formatted metadata records.
-
Routing – route for the request.
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.