Spring Boot used RSocket
1 Overview
RSocket
Support application layer protocol Reactive Streams
semantics, eg: RSocket As an alternative to the HTTP. In this tutorial, we will see the RSocket
use in spring boot, especially how spring boot to help lower-level abstract RSocket API.
2. dependence
Let's add spring-boot-starter-rsocket
come to rely on:
<dependency>
<groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-rsocket</artifactId> </dependency>
This pull will take depends transitive RSocket
related dependencies, such as: rsocket-core
and rsocket-transport-netty
3. Example of application
Now continue our simple application. To highlight the RSocket
interactive mode provides, I intend to create a trading application, transaction applications including client and server.
3.1. Server Settings
First, we set the boot by springboot application RSocket server
server. Because of spring-boot-starter-rsocket dependency
dependence, so springboot configured automatically RSocket server
. As usual, you can use attribute-driven way to modify RSocket server
the default configuration values. For example: by increasing a configuration application.properties
, the modified RSocket
port
spring.rsocket.server.port=7000
You can further modify other properties of the server as needed
3.2. Setting up the client
Next, we set up a client, but also a springboot application. Although springboot automatically configure most RSocket related components, but also customize some objects to complete the setup.
@Configuration
public class ClientConfiguration {
@Bean
public RSocket rSocket() {
return RSocketFactory
.connect()
.mimeType(MimeTypeUtils.APPLICATION_JSON_VALUE, MimeTypeUtils.APPLICATION_JSON_VALUE)
.frameDecoder(PayloadDecoder.ZERO_COPY)
.transport(TcpClientTransport.create(7000))
.start()
.block();
}
@Bean
RSocketRequester rSocketRequester(RSocketStrategies rSocketStrategies) {
return RSocketRequester.wrap(rSocket(), MimeTypeUtils.APPLICATION_JSON, rSocketStrategies);
}
}
Here we are creating RSocket
a client and configured TCP port: 7000. Note: The service port we have already been configured. Next we define a decorative object of RSocket RSocketRequester
. The objects we like RSocket server
when interacting will help us. After you define these objects are configured, we just have a skeleton. In the next, we will be exposed to different interaction modes, and see springboot assist in this place.
4. springboot RSocket
During manner Request/Response
We from Request/Response
the beginning, HTTP
also use this means of communication, which is the most common, most similar to the interactive mode. In this interactive mode, the initialization of the communication from the client and sends a request. Thereafter, the server performs an operation, and returns a response to the client - when communication is completed. In our trading application where a client asks a given stock's current market data. In response, the server will transfer the requested data.
4.1 Server
In the server side, we should first create a controller
to hold our processor method. We will use @MessageMapping
annotations instead of SpringMVC like @RequestMapping
or @GetMapping
comment
@Controller
public class MarketDataRSocketController {
private final MarketDataRepository marketDataRepository;
public MarketDataRSocketController(MarketDataRepository marketDataRepository) {
this.marketDataRepository = marketDataRepository;
}
@MessageMapping("currentMarketData")
public Mono<MarketData> currentMarketData(MarketDataRequest marketDataRequest) {
return marketDataRepository.getOne(marketDataRequest.getStock());
}
}
To study under our control. We will use @Controller
annotations to define a controller to handle the request to enter RSocket. In addition, annotations @MessageMapping
let us define the route and we are interested in how to respond to a request. In this example, the server listens for Router currentMarketData
, and a single result in response Mono<MarketData>
to the client.
4.2 Client
Next, our RSocket client should ask the price of a stock and get a single response. To initialize request, we use the RSocketRequester
classes, as follows:
@RestController
public class MarketDataRestController {
private final RSocketRequester rSocketRequester;
public MarketDataRestController(RSocketRequester rSocketRequester) {
this.rSocketRequester = rSocketRequester;
}
@GetMapping(value = "/current/{stock}")
public Publisher<MarketData> current(@PathVariable("stock") String stock) {
return rSocketRequester
.route("currentMarketData")
.data(new MarketDataRequest(stock))
.retrieveMono(MarketData.class);
}
}
Note: In the example, RSocket
the client is also a REST
style controller
, a way to access our RSocket
servers. Therefore, we use @RestController
and @GetMapping
annotations to define our request / response endpoint. In the endpoint method, we use the class RSocketRequester
and specify the route. In fact, this is the server side RSocket
of the desired route, then we pass the request data. Finally, when you call retrieveMono()
upon method, springboot will help us initiate a request / response interaction.
5. Spring Boot RSocket
The Fire And Forget
pattern
Next we will look at Fire And Forget
interactive mode. As the name hints, like, the client sends a request to the server, but do not expect the server returns a response back. In our trading program, some clients will serve as a data resource, and push the market data to the server.
5.1 server
Let's create another endpoint in our server application, as follows:
@MessageMapping("collectMarketData")
public Mono<Void> collectMarketData(MarketData marketData) { marketDataRepository.add(marketData); return Mono.empty(); }
Again, we define a new @MessageMapping
route for collectMarketData
. Further, Spring Boot automatically convert the incoming load an MarketData
instance. However, the biggest difference here is that we return to a Mono<Void>
, because the client does not need to return to the server.
5.2 Client
To see how we initialize our fire-and-forget
request mode. We will create another style REST endpoint, as follows:
@GetMapping(value = "/collect")
public Publisher<Void> collect() {
return rSocketRequester
.route("collectMarketData") .data(getMarketData()) .send(); }
Here we specify routing and load would be an MarketData
example. Since we use the send()
method instead retrieveMono()
, all interaction patterns into a fire-and-forget
pattern.
6. Spring Boot RSocket
During mannerRequest Stream
Request stream is a more complex interactive mode, the client sends a request to this mode, it acquires from the server to the plurality of response over time. To simulate this interaction model, the client will ask for all market data for a given stock.
6.1 server
We started from the server. We will add another message mapping method, as follows:
@MessageMapping("feedMarketData")
public Flux<MarketData> feedMarketData(MarketDataRequest marketDataRequest) {
return marketDataRepository.getAll(marketDataRequest.getStock());
}
As you can see, this method with other processors processor method is very similar. Different parts of our return to a Flux<MarketData>
place of Mono<MarketData>
. Finally, our RSocket server will return multiple responses to the client.
6.2 Client
In the client side, we create an endpoint initialization request / response communication, as follows:
@GetMapping(value = "/feed/{stock}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Publisher<MarketData> feed(@PathVariable("stock") String stock) {
return rSocketRequester
.route("feedMarketData")
.data(new MarketDataRequest(stock))
.retrieveFlux(MarketData.class);
}
We studied under RSocket request. First we define the routing requests and load. Then, we define the use of retrieveFlux()
response desired call. This section determines the interactive mode. Also note: As our client is REST
the style of the server, the client also defines the response of the media type MediaType.TEXT_EVENT_STREAM_VALUE
.
7. handling exceptions
Now let us look at the server program, how declarative way to handle exceptions. When the processing request / response, I can use simple @MessageExceptionHandler
annotations, as follows:
@MessageExceptionHandler
public Mono<MarketData> handleException(Exception e) {
return Mono.just(MarketData.fromException(e));
}
Here we give notes marked as exception handling @MessageExceptionHandler
. As a result, this method will handle all types of exceptions, as Exception
are all other types of abnormal superclass. We can also explicitly create more different types, different exception handling. This is of course the request / response mode, and we return is Mono<MarketData>
. We expect this type of response with the return type of our interactive mode matches.
8. Conclusion
In this tutorial, we introduced RSocket support springboot and a detailed list of the different interactive mode RSocket provided. See all the sample code at GitHub on.
Original link: www.baeldung.com/spring-boot...
Author: baeldung
Translator: sleeve