This Demo
This is the multi-casting Flux variation of the standard WebSocket Service seen here
WebSocket Server
Spring’s reactive [WebSocket] API is a part of Spring 5’s WebFlux API which bring reactive flow control to our projects via project reactor. We will introduce a single WebSocket handler, and show whats needed to get started using Spring’s WebSocketServer
support.
You’ll want to start a new Spring project using start.spring.io[this link] to autogenerate a maven based POM. If you go with a different approach, just make sure to have webflux
, and lombok
projects.
First, wire in a WebSocketHandlerAdapter
to handle our web socket handshake, upgrade, and other connection details.
socket_handler_adapter.
@Bean
WebSocketHandlerAdapter socketHandlerAdapter() {
return new WebSocketHandlerAdapter();
}
Next, create the WebSocket session handler. The simplest way to do this to use the functional interface for WebSocketHandler
and implement it’s handle method to manage our stream response. In this, we will use the Flux.interval
operator and push it’s output back to the session.
socket_session_handler.
WebSocketHandler webSocketHandler(ConnectableFlux<String> publisher) {
return session ->
session.send(publisher.map(session::textMessage))
.doOnSubscribe(sub -> log.info(session.getId() + ".CONNECT"))
.doFinally(sig -> log.info(session.getId() + ".DISCONNECT"));
}
We utilize the ConnectableFlux<String>
to hot
publish our tick data to websocket clients. That is, in contrast to the last demonstration which produced a cold
published flow.
Finally, to map URI’s to our handler we wire in a reactive SimpleUrlHandlerMapping
to delegate socket connections on URL /ws/feed
.
uri_handler_mapping.
@Bean
HandlerMapping simpleUrlHandlerMapping() {
SimpleUrlHandlerMapping simpleUrlHandlerMapping = new SimpleUrlHandlerMapping();
RequestMappingHandlerMapping foo = new RequestMappingHandlerMapping();
simpleUrlHandlerMapping.setUrlMap(Collections.singletonMap("/ws/feed",
webSocketHandler()));
simpleUrlHandlerMapping.setOrder(10);
return simpleUrlHandlerMapping;
}
Finally, we will execute this server app:
server_app_main.
public static void main(String[] args) {
SpringApplication.run(WebSocketConfiguration.class, args);
}
Start the application:
$ mvn clean spring-boot:run
...
INFO 10671 --- [ main] o.s.b.web.embedded.netty.NettyWebServer : Netty started on port(s): 8080
Now we are ready to implement the client, and demonstrate the new server we just stood up!
References/Readling List
Spring WebFlux guide
Articles
W3C Proposals
Theory