Getting started with RSocket in Spring Boot
Tags: tutorial, java, spring, rsocket
Published: 2019-06-10 14:21:29

# Introduction

RSocket is a binary protocol for use on byte stream transports such as TCP, WebSockets, and Aeron.

It enables the following symmetric interaction models via async message passing over a single connection:

* request/response (stream of 1)
* request/stream (finite stream of many)
* fire-and-forget (no response)
* event subscription (infinite stream of many)

It supports session resumption, to allow resuming long-lived streams across different transport connections. This is particularly useful for mobile⬄server communication when network connections drop, switch, and reconnect frequently.

In our tutorial, we will implement RSocket using the Java programming language.

# Why Springboot

Although I could simply implement RSocket with a simple Java application, I chose Springboot because it's a huge project on the JVM languages ecosystem. Springboot doesn't have a stable version for RSocket yet, but that shouldn't stop us experimenting with it.

# Structure

Our project will consist of two sub-projects. The __Consumer__, who will do the requests and the __Producer__, who will provide the __Consumer__ with data.

# Getting Started

If you want to easily get started with a Springboot project I recommend always using the [Spring Initializr](https://start.spring.io/). 

## Configuring Gradle

First of all we have to configure our build.gradle and include the rsocket-starter-dependency from Springboot:

{% gist https://gist.github.com/Petros0/faa49f161e80325e15ef11b126d13fe5 %}

For the __Consumer__ we should include also the reactive-web-starter dependency, because we want to somehow display the data that we receive from the __Producer__.

{% gist https://gist.github.com/Petros0/667da51b3d1b280aeb2906b707266729 %}


# Configuration

Now let's get our hands dirty and write some code :wink:.

## Producer

First we have to configure in which port will our __Producer__ receive new connections:

{% gist https://gist.github.com/Petros0/9bcd36a36808839717ec687ed9e7b51f %}

The `spring.rsocket.server.port=7000` configures the RSocket to start listening on port 7000 and the `spring.main.lazy-initialization=true` is to make sure that Springboot will initialize its beans lazily.


## Consumer

Now, here, we configure the RSocket client, by creating two _Beans_ of type _RSocket_ and _RSocketRequester_. The _RSocket bean_ is used to create the connection to the __Producer__. The _RSocketRequester bean_ is like our `WebClient` (if we are using Reactive) or the `RestTemplate` (if we are using MVC), he will do the requests to __Producer__.


{% gist https://gist.github.com/Petros0/1c4c509456d02b25429686a9d16b3296 %}

# The Actual Code

Our two applications (the __Producer__ and the __Consumer__) will use the following domain objects for their communication:

{% gist https://gist.github.com/Petros0/b3d22cdaf11bdb7d52baa902acba34b3 %}

## Simple Communication

Let's start with an easy example, a simple Request with a single Response.

### Producer

{% gist https://gist.github.com/Petros0/27fa8ba585fe0292aa9c0ad106753b53 %}

If you ever used WebSockets with Springboot the `@MessageMapping` annotation should be familiar.
Here, with the `@MessageMapping("greet")` we specify the route "greet", which receives a `GreetingsRequest` and returns a single object `GreetingsResponse` as a response.

### Consumer

{% gist https://gist.github.com/Petros0/fa58e50927c1eeeb5aed8d3d15598f13 %}

Here we see a simple `@RestController` which injects the `RSocketRequester` (the one we configured earlier) and uses him to do the Request. As you see, we tell the `requester` to do a Request to the "greet" route (which we configured earlier in the __Producer__).

## Communication with Stream

Delivering a stream of data with RSocket comes natural and with not that much of an effort.

### Producer

{% gist https://gist.github.com/Petros0/ac1520481b287ea1b5ab9a95155a9150 %}

As you see in the gist above, we configured our `@MessageMapping` as before, but now we return a Flux (don't know what Mono and Flux are? Check this [StackOverflow post](https://stackoverflow.com/questions/47988433/mono-vs-flux-in-reactive-stream)). 

We also use the `.delayElements()` method to simulate a delay between our responses.

### Consumer

{% gist https://gist.github.com/Petros0/d2528656b338b9002b6cad6c07ba5d34 %}

Not much have changed from our other request to the __Producer__, clearly the `.route("greet-stream")`. But if you see carefully, now our `@GetMapping` produces a `text/event-stream` and not the default `application/json`.

Let's check the result!

![Greet Stream](https://raw.githubusercontent.com/Petros0/springboot-rsocket/master/img/greet-stream.gif)


# Closing thoughts

So, that was it! I hope I gave you a clear explanation on how to use the new RSocket protocol!

You can find the project here: 

{% github Petros0/springboot-rsocket %}

Thanks for reading and have fun!

# Resources

* [RSocket](http://rsocket.io/)
* [SpringTips from Josh](https://www.youtube.com/watch?v=BxHqeq58xrE)