14.3 Transporting RSocket over WebSocket
By default, RSocket communication takes place over a TCP socket. But in some cases, TCP isn’t an option. Consider the following two situations:
- The client is written in JavaScript and is running in a user’s web browser.
- The client must cross a gateway or firewall boundary to get to the server, and the firewall doesn’t allow communication over arbitrary ports.
Moreover, WebSocket itself lacks any support for routing, requiring that routing details be defined at the application level. By layering RSocket over WebSocket, WebSocket will benefit from RSocket’s built-in routing support.
In these situations, RSocket can be transported over WebSocket. WebSocket communication takes place over HTTP, which is the primary means of communication in all web browsers and is usually allowed through firewalls.
To switch from the TCP transport to the WebSocket transport, you need to make only a few minor changes in the server and client. To start, because WebSocket is carried over HTTP, you need to be sure that the server-side application supports handling HTTP requests. Put simply, you need to add the following WebFlux starter dependency to the project build (if it’s not already there):
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>You also need to specify that you want to use the WebSocket transport in the serverside configuration by setting the spring.rsocket.server.transport property. Also, you need to set the HTTP path that the RSocket communication will take place on by setting spring.rsocket.server.mapping-path. The server’s configuration will look like this in application.yml:
spring:
rsocket:
server:
transport: websocket
mapping-path: /rsocketUnlike the TCP transport, which communicates over a specific port, the WebSocket transport works over a specific HTTP path. Thus, there is no need to set spring.rsocket.server.port as with RSocket over TCP.
That’s all you’ll need to do on the server side to enable WebSocket transport for RSocket. Everything else will work exactly the same as with TCP.
On the client side, only one small change is required. Rather than create a TCPbased requester, you want to create a WebSocket-based requester by calling the websocket() method on the RSocketRequester.Builder like so:
RSocketRequester requester = requesterBuilder.websocket(
URI.create("ws://localhost:8080/rsocket"));
requester
.route("greeting")
.data("Hello RSocket!")
.retrieveMono(String.class)
.subscribe(response -> log.info("Got a response: " + response));And that’s all there is to transporting RSocket over WebSocket!
