liveBook · Manning

RSocket

As explained in Spring in Action, Sixth Edition

RSocket is a binary application protocol that supports reactive interaction patterns including request-response, request-stream, and fire-and-forget communication.

RSocket is an asynchronous binary protocol for communication between applications. Like HTTP, it can handle one request and one response. Unlike a typical HTTP request-response exchange, it also supports response streams, messages that need no reply, and ongoing two-way communication. Its Reactive Streams foundation fits reactive types such as Mono and Flux. section 14.1

Choose the communication model that matches the exchange:

  • Request-response: send one request and receive one response. section 14.1
  • Request-stream: send one request and receive zero or more values. section 14.1
  • Fire-and-forget: send a message without expecting a response. section 14.1
  • Channel: keep a bidirectional exchange open so either side can send data. section 14.1

In Spring Boot, add spring-boot-starter-rsocket to both the server and client. An RSocket server can use a controller much like a web service does, but @MessageMapping selects a message route rather than an HTTP path. A handler can accept a Mono<String> payload and return a Mono<String> response. For TCP transport, configure the server’s listening port; a client connects with RSocketRequester.Builder.tcp(). section 14.2 section 14.2.1

Listing 14.2 A simple RSocket request-response server
package rsocket;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.stereotype.Controller;
import lombok.extern.slf4j.Slf4j;
import reactor.core.publisher.Mono;
 
@Controller
@Slf4j
public class GreetingController {
 
    @MessageMapping("greeting")
    public Mono<String> handleGreeting(Mono<String> greetingMono) {
        return greetingMono
            .doOnNext(greeting -> 
                log.info("Received a greeting: {}", greeting))
            .map(greeting -> "Hello back to you!");
    }
    
}

This greeting controller shows a complete request-response handler: @MessageMapping selects the route, and Mono carries the incoming greeting and outgoing reply. section 14.2.1

Listing 14.3 Sending a request from a client
RSocketRequester tcp = requesterBuilder.tcp("localhost", 7000);
 
// ... send messages with RSocketRequester ...
tcp
  .route("greeting")
  .data("Hello RSocket!")
  .retrieveMono(String.class)
  .subscribe(response -> log.info("Got a response: {}", response));

This client sends a greeting to the matching route, retrieves a Mono<String>, and subscribes to log the reply. section 14.2.1

TCP is the default transport. If a browser client or firewall makes direct TCP impractical, carry RSocket over WebSocket instead. Add the WebFlux starter to the server, set spring.rsocket.server.transport to websocket and spring.rsocket.server.mapping-path to an HTTP path, then create the client requester with websocket() rather than tcp(). The message routes and handlers can stay the same. section 14.3

How Spring in Action, Sixth Edition covers it

How deep it goes
Defines four interaction models and works through Spring request-response server and client code, then shows WebSocket transport changes.
Examples
Shows a greeting route, a client sending “Hello RSocket!”, TCP port configuration, and WebSocket mapping configuration.
What it assumes
Assumes familiarity with Mono and Flux while introducing RSocket’s models and showing the dependency needed to begin.
What you can do after
Build it from scratch using Spring Boot controllers and RSocketRequester, and configure either TCP or WebSocket transport.
How it connects
Connects Reactive Streams, Mono, Flux, Spring controllers, RSocketRequester, TCP, and WebSocket.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Spring in Action, Sixth Edition. The section links point to the parts of the book it draws on.