This part of the reference documentation covers support for Reactive stack, WebSocket messaging.
The Spring Framework provides a WebSocket API that can be used to write client and server side applications that handle WebSocket messages.
Creating a WebSocket server is as simple as implementing WebSocketHandler
:
import org.springframework.web.reactive.socket.WebSocketHandler;
import org.springframework.web.reactive.socket.WebSocketSession;
public class MyWebSocketHandler implements WebSocketHandler {
@Override
public Mono<Void> handle(WebSocketSession session) {
// ...
}
}
Spring WebFlux provides a WebSocketHandlerAdapter
that can adapt WebSocket
requests and use the above handler to handle the resulting WebSocket session. After the
adapter is registered as a bean, you can map requests to your handler, for example using
SimpleUrlHandlerMapping
. This is shown below:
@Configuration
static class WebConfig {
@Bean
public HandlerMapping handlerMapping() {
Map<String, WebSocketHandler> map = new HashMap<>();
map.put("/path", new MyWebSocketHandler());
SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
mapping.setUrlMap(map);
mapping.setOrder(-1); // before annotated controllers
return mapping;
}
@Bean
public WebSocketHandlerAdapter handlerAdapter() {
return new WebSocketHandlerAdapter();
}
}
WebSocketHandlerAdapter
does not perform WebSocket handshakes itself. Instead it
delegates to an instance of WebSocketService
. The default WebSocketService
implementation is HandshakeWebSocketService
.
The HandshakeWebSocketService
performs basic checks on the WebSocket request and
delegates to a server-specific RequestUpgradeStrategy
. At present upgrade strategies
exist for Reactor Netty, Tomcat, Jetty, and Undertow.
The RequestUpgradeStrategy
for each server exposes the WebSocket-related configuration
options available for the underlying WebSocket engine. Below is an example of setting
WebSocket options when running on Tomcat:
@Configuration
static class WebConfig {
@Bean
public WebSocketHandlerAdapter handlerAdapter() {
return new WebSocketHandlerAdapter(webSocketService());
}
@Bean
public WebSocketService webSocketService() {
TomcatRequestUpgradeStrategy strategy = new TomcatRequestUpgradeStrategy();
strategy.setMaxSessionIdleTimeout(0L);
return new HandshakeWebSocketService(strategy);
}
}
Check the upgrade strategy for your server to see what options are available. Currently only Tomcat and Jetty expose such options.
The easiest way to configure CORS and restrict access to a WebSocket endpoint is to
have your WebSocketHandler
implement CorsConfigurationSource
and return a
CorsConfiguraiton
with allowed origins, headers, etc. If for any reason you can’t do
that, you can also set the corsConfigurations
property on the SimpleUrlHandler
to
specify CORS settings by URL pattern. If both are specified they’re combined via the
combine
method on CorsConfiguration
.
Spring WebFlux provides a WebSocketClient
abstraction with implementations for
Reactor Netty, Tomcat, Jetty, Undertow, and standard Java (i.e. JSR-356).
Note
|
The Tomcat client is effectively an extension of the standard Java one with some extra
functionality in the |
To start a WebSocket session, create an instance of the client and use its execute
methods:
WebSocketClient client = new ReactorNettyWebSocketClient();
URI url = new URI("ws://localhost:8080/path");
client.execute(url, session ->
session.receive()
.doOnNext(System.out::println)
.then());
Some clients, e.g. Jetty, implement Lifecycle
and need to be started in stopped
before you can use them. All clients have constructor options related to configuration
of the underlying WebSocket client.