Use code includes and tabs in WebSocket documentation
See gh-22171
This commit is contained in:
@@ -82,49 +82,9 @@ https://sockjs.github.io/sockjs-protocol/sockjs-protocol-0.3.3.html[narrated tes
|
||||
[[websocket-fallback-sockjs-enable]]
|
||||
== Enabling SockJS
|
||||
|
||||
You can enable SockJS through Java configuration, as the following example shows:
|
||||
You can enable SockJS through configuration, as the following example shows:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
@Configuration
|
||||
@EnableWebSocket
|
||||
public class WebSocketConfig implements WebSocketConfigurer {
|
||||
|
||||
@Override
|
||||
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
|
||||
registry.addHandler(myHandler(), "/myHandler").withSockJS();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public WebSocketHandler myHandler() {
|
||||
return new MyHandler();
|
||||
}
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
The following example shows the XML configuration equivalent of the preceding example:
|
||||
|
||||
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
||||
----
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:websocket="http://www.springframework.org/schema/websocket"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans
|
||||
https://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/websocket
|
||||
https://www.springframework.org/schema/websocket/spring-websocket.xsd">
|
||||
|
||||
<websocket:handlers>
|
||||
<websocket:mapping path="/myHandler" handler="myHandler"/>
|
||||
<websocket:sockjs/>
|
||||
</websocket:handlers>
|
||||
|
||||
<bean id="myHandler" class="org.springframework.samples.MyHandler"/>
|
||||
|
||||
</beans>
|
||||
----
|
||||
include-code::./WebSocketConfiguration[tag=snippet,indent=0]
|
||||
|
||||
The preceding example is for use in Spring MVC applications and should be included in the
|
||||
configuration of a xref:web/webmvc/mvc-servlet.adoc[`DispatcherServlet`]. However, Spring's WebSocket
|
||||
|
||||
@@ -16,69 +16,12 @@ Creating a WebSocket server is as simple as implementing `WebSocketHandler` or,
|
||||
likely, extending either `TextWebSocketHandler` or `BinaryWebSocketHandler`. The following
|
||||
example uses `TextWebSocketHandler`:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
import org.springframework.web.socket.WebSocketHandler;
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
import org.springframework.web.socket.TextMessage;
|
||||
include-code::./MyHandler[tag=snippet,indent=0]
|
||||
|
||||
public class MyHandler extends TextWebSocketHandler {
|
||||
|
||||
@Override
|
||||
public void handleTextMessage(WebSocketSession session, TextMessage message) {
|
||||
// ...
|
||||
}
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
There is dedicated WebSocket Java configuration and XML namespace support for mapping the preceding
|
||||
There is dedicated WebSocket programmatic configuration and XML namespace support for mapping the preceding
|
||||
WebSocket handler to a specific URL, as the following example shows:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
import org.springframework.web.socket.config.annotation.EnableWebSocket;
|
||||
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
|
||||
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
|
||||
|
||||
@Configuration
|
||||
@EnableWebSocket
|
||||
public class WebSocketConfig implements WebSocketConfigurer {
|
||||
|
||||
@Override
|
||||
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
|
||||
registry.addHandler(myHandler(), "/myHandler");
|
||||
}
|
||||
|
||||
@Bean
|
||||
public WebSocketHandler myHandler() {
|
||||
return new MyHandler();
|
||||
}
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
The following example shows the XML configuration equivalent of the preceding example:
|
||||
|
||||
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
||||
----
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:websocket="http://www.springframework.org/schema/websocket"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans
|
||||
https://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/websocket
|
||||
https://www.springframework.org/schema/websocket/spring-websocket.xsd">
|
||||
|
||||
<websocket:handlers>
|
||||
<websocket:mapping path="/myHandler" handler="myHandler"/>
|
||||
</websocket:handlers>
|
||||
|
||||
<bean id="myHandler" class="org.springframework.samples.MyHandler"/>
|
||||
|
||||
</beans>
|
||||
----
|
||||
include-code::./WebSocketConfiguration[tag=snippet,indent=0]
|
||||
|
||||
The preceding example is for use in Spring MVC applications and should be included
|
||||
in the configuration of a xref:web/webmvc/mvc-servlet.adoc[`DispatcherServlet`]. However, Spring's
|
||||
@@ -104,45 +47,7 @@ You can use such an interceptor to preclude the handshake or to make any attribu
|
||||
available to the `WebSocketSession`. The following example uses a built-in interceptor
|
||||
to pass HTTP session attributes to the WebSocket session:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
@Configuration
|
||||
@EnableWebSocket
|
||||
public class WebSocketConfig implements WebSocketConfigurer {
|
||||
|
||||
@Override
|
||||
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
|
||||
registry.addHandler(new MyHandler(), "/myHandler")
|
||||
.addInterceptors(new HttpSessionHandshakeInterceptor());
|
||||
}
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
The following example shows the XML configuration equivalent of the preceding example:
|
||||
|
||||
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
||||
----
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:websocket="http://www.springframework.org/schema/websocket"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans
|
||||
https://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/websocket
|
||||
https://www.springframework.org/schema/websocket/spring-websocket.xsd">
|
||||
|
||||
<websocket:handlers>
|
||||
<websocket:mapping path="/myHandler" handler="myHandler"/>
|
||||
<websocket:handshake-interceptors>
|
||||
<bean class="org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor"/>
|
||||
</websocket:handshake-interceptors>
|
||||
</websocket:handlers>
|
||||
|
||||
<bean id="myHandler" class="org.springframework.samples.MyHandler"/>
|
||||
|
||||
</beans>
|
||||
----
|
||||
include-code::./WebSocketConfiguration[tag=snippet,indent=0]
|
||||
|
||||
A more advanced option is to extend the `DefaultHandshakeHandler` that performs
|
||||
the steps of the WebSocket handshake, including validating the client origin,
|
||||
@@ -236,69 +141,17 @@ You can configure of the underlying WebSocket server such as input message buffe
|
||||
idle timeout, and more.
|
||||
|
||||
For Jakarta WebSocket servers, you can add a `ServletServerContainerFactoryBean` to your
|
||||
Java configuration. For example:
|
||||
configuration. For example:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
@Bean
|
||||
public ServletServerContainerFactoryBean createWebSocketContainer() {
|
||||
ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
|
||||
container.setMaxTextMessageBufferSize(8192);
|
||||
container.setMaxBinaryMessageBufferSize(8192);
|
||||
return container;
|
||||
}
|
||||
----
|
||||
|
||||
Or to your XML configuration:
|
||||
|
||||
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
||||
----
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:websocket="http://www.springframework.org/schema/websocket"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans
|
||||
https://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/websocket
|
||||
https://www.springframework.org/schema/websocket/spring-websocket.xsd">
|
||||
|
||||
<bean class="org.springframework...ServletServerContainerFactoryBean">
|
||||
<property name="maxTextMessageBufferSize" value="8192"/>
|
||||
<property name="maxBinaryMessageBufferSize" value="8192"/>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
----
|
||||
include-code::./WebSocketConfiguration[tag=snippet,indent=0]
|
||||
|
||||
NOTE: For client Jakarta WebSocket configuration, use
|
||||
ContainerProvider.getWebSocketContainer() in Java configuration, or
|
||||
ContainerProvider.getWebSocketContainer() in programmatic configuration, or
|
||||
`WebSocketContainerFactoryBean` in XML.
|
||||
|
||||
For Jetty, you can supply a `Consumer` callback to configure the WebSocket server:
|
||||
For Jetty, you can supply a callback to configure the WebSocket server:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
@Configuration
|
||||
@EnableWebSocket
|
||||
public class WebSocketConfig implements WebSocketConfigurer {
|
||||
|
||||
@Override
|
||||
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
|
||||
registry.addHandler(echoWebSocketHandler(), "/echo").setHandshakeHandler(handshakeHandler());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DefaultHandshakeHandler handshakeHandler() {
|
||||
JettyRequestUpgradeStrategy strategy = new JettyRequestUpgradeStrategy();
|
||||
strategy.addWebSocketConfigurer(configurable -> {
|
||||
policy.setInputBufferSize(8192);
|
||||
policy.setIdleTimeout(600000);
|
||||
});
|
||||
return new DefaultHandshakeHandler(strategy);
|
||||
}
|
||||
|
||||
}
|
||||
----
|
||||
include-code::./JettyWebSocketConfiguration[tag=snippet,indent=0]
|
||||
|
||||
TIP: When using STOMP over WebSocket, you will also need to configure
|
||||
xref:web/websocket/stomp/server-config.adoc[STOMP WebSocket transport]
|
||||
@@ -331,51 +184,4 @@ The three possible behaviors are:
|
||||
|
||||
You can configure WebSocket and SockJS allowed origins, as the following example shows:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
import org.springframework.web.socket.config.annotation.EnableWebSocket;
|
||||
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
|
||||
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
|
||||
|
||||
@Configuration
|
||||
@EnableWebSocket
|
||||
public class WebSocketConfig implements WebSocketConfigurer {
|
||||
|
||||
@Override
|
||||
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
|
||||
registry.addHandler(myHandler(), "/myHandler").setAllowedOrigins("https://mydomain.com");
|
||||
}
|
||||
|
||||
@Bean
|
||||
public WebSocketHandler myHandler() {
|
||||
return new MyHandler();
|
||||
}
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
The following example shows the XML configuration equivalent of the preceding example:
|
||||
|
||||
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
||||
----
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:websocket="http://www.springframework.org/schema/websocket"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans
|
||||
https://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/websocket
|
||||
https://www.springframework.org/schema/websocket/spring-websocket.xsd">
|
||||
|
||||
<websocket:handlers allowed-origins="https://mydomain.com">
|
||||
<websocket:mapping path="/myHandler" handler="myHandler" />
|
||||
</websocket:handlers>
|
||||
|
||||
<bean id="myHandler" class="org.springframework.samples.MyHandler"/>
|
||||
|
||||
</beans>
|
||||
----
|
||||
|
||||
|
||||
|
||||
|
||||
include-code::./WebSocketConfiguration[tag=snippet,indent=0]
|
||||
|
||||
@@ -40,29 +40,7 @@ the user header on the CONNECT `Message`. Spring notes and saves the authenticat
|
||||
user and associate it with subsequent STOMP messages on the same session. The following
|
||||
example shows how to register a custom authentication interceptor:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
@Configuration
|
||||
@EnableWebSocketMessageBroker
|
||||
public class MyConfig implements WebSocketMessageBrokerConfigurer {
|
||||
|
||||
@Override
|
||||
public void configureClientInboundChannel(ChannelRegistration registration) {
|
||||
registration.interceptors(new ChannelInterceptor() {
|
||||
@Override
|
||||
public Message<?> preSend(Message<?> message, MessageChannel channel) {
|
||||
StompHeaderAccessor accessor =
|
||||
MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
|
||||
if (StompCommand.CONNECT.equals(accessor.getCommand())) {
|
||||
Authentication user = ... ; // access authentication header(s)
|
||||
accessor.setUser(user);
|
||||
}
|
||||
return message;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
----
|
||||
include-code::./WebSocketConfiguration[tag=snippet,indent=0]
|
||||
|
||||
Also, note that, when you use Spring Security's authorization for messages, at present,
|
||||
you need to ensure that the authentication `ChannelInterceptor` config is ordered
|
||||
|
||||
@@ -62,42 +62,7 @@ documentation of the XML schema for important additional details.
|
||||
|
||||
The following example shows a possible configuration:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
@Configuration
|
||||
@EnableWebSocketMessageBroker
|
||||
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
|
||||
|
||||
@Override
|
||||
public void configureWebSocketTransport(WebSocketTransportRegistration registration) {
|
||||
registration.setSendTimeLimit(15 * 1000).setSendBufferSizeLimit(512 * 1024);
|
||||
}
|
||||
|
||||
// ...
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
The following example shows the XML configuration equivalent of the preceding example:
|
||||
|
||||
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
||||
----
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:websocket="http://www.springframework.org/schema/websocket"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans
|
||||
https://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/websocket
|
||||
https://www.springframework.org/schema/websocket/spring-websocket.xsd">
|
||||
|
||||
<websocket:message-broker>
|
||||
<websocket:transport send-timeout="15000" send-buffer-size="524288" />
|
||||
<!-- ... -->
|
||||
</websocket:message-broker>
|
||||
|
||||
</beans>
|
||||
----
|
||||
include-code::./WebSocketConfiguration[tag=snippet,indent=0]
|
||||
|
||||
You can also use the WebSocket transport configuration shown earlier to configure the
|
||||
maximum allowed size for incoming STOMP messages. In theory, a WebSocket
|
||||
@@ -115,42 +80,7 @@ minimum.
|
||||
|
||||
The following example shows one possible configuration:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
@Configuration
|
||||
@EnableWebSocketMessageBroker
|
||||
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
|
||||
|
||||
@Override
|
||||
public void configureWebSocketTransport(WebSocketTransportRegistration registration) {
|
||||
registration.setMessageSizeLimit(128 * 1024);
|
||||
}
|
||||
|
||||
// ...
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
The following example shows the XML configuration equivalent of the preceding example:
|
||||
|
||||
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
||||
----
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:websocket="http://www.springframework.org/schema/websocket"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans
|
||||
https://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/websocket
|
||||
https://www.springframework.org/schema/websocket/spring-websocket.xsd">
|
||||
|
||||
<websocket:message-broker>
|
||||
<websocket:transport message-size="131072" />
|
||||
<!-- ... -->
|
||||
</websocket:message-broker>
|
||||
|
||||
</beans>
|
||||
----
|
||||
include-code::./MessageSizeLimitWebSocketConfiguration[tag=snippet,indent=0]
|
||||
|
||||
An important point about scaling involves using multiple application instances.
|
||||
Currently, you cannot do that with the simple broker.
|
||||
|
||||
@@ -6,65 +6,14 @@ When messages are routed to `@MessageMapping` methods, they are matched with
|
||||
This is a good convention in web applications and similar to HTTP URLs. However, if
|
||||
you are more used to messaging conventions, you can switch to using dot (`.`) as the separator.
|
||||
|
||||
The following example shows how to do so in Java configuration:
|
||||
The following example shows how to do so:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
@Configuration
|
||||
@EnableWebSocketMessageBroker
|
||||
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
|
||||
|
||||
// ...
|
||||
|
||||
@Override
|
||||
public void configureMessageBroker(MessageBrokerRegistry registry) {
|
||||
registry.setPathMatcher(new AntPathMatcher("."));
|
||||
registry.enableStompBrokerRelay("/queue", "/topic");
|
||||
registry.setApplicationDestinationPrefixes("/app");
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
The following example shows the XML configuration equivalent of the preceding example:
|
||||
|
||||
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
||||
----
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:websocket="http://www.springframework.org/schema/websocket"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans
|
||||
https://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/websocket
|
||||
https://www.springframework.org/schema/websocket/spring-websocket.xsd">
|
||||
|
||||
<websocket:message-broker application-destination-prefix="/app" path-matcher="pathMatcher">
|
||||
<websocket:stomp-endpoint path="/stomp"/>
|
||||
<websocket:stomp-broker-relay prefix="/topic,/queue" />
|
||||
</websocket:message-broker>
|
||||
|
||||
<bean id="pathMatcher" class="org.springframework.util.AntPathMatcher">
|
||||
<constructor-arg index="0" value="."/>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
----
|
||||
include-code::./WebSocketConfiguration[tag=snippet,indent=0]
|
||||
|
||||
After that, a controller can use a dot (`.`) as the separator in `@MessageMapping` methods,
|
||||
as the following example shows:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
@Controller
|
||||
@MessageMapping("red")
|
||||
public class RedController {
|
||||
|
||||
@MessageMapping("blue.{green}")
|
||||
public void handleGreen(@DestinationVariable String green) {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
----
|
||||
include-code::./RedController[tag=snippet,indent=0]
|
||||
|
||||
The client can now send a message to `/app/red.blue.green123`.
|
||||
|
||||
|
||||
@@ -5,56 +5,7 @@ STOMP over WebSocket support is available in the `spring-messaging` and
|
||||
`spring-websocket` modules. Once you have those dependencies, you can expose a STOMP
|
||||
endpoint over WebSocket, as the following example shows:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
|
||||
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
|
||||
|
||||
@Configuration
|
||||
@EnableWebSocketMessageBroker
|
||||
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
|
||||
|
||||
@Override
|
||||
public void registerStompEndpoints(StompEndpointRegistry registry) {
|
||||
registry.addEndpoint("/portfolio"); // <1>
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configureMessageBroker(MessageBrokerRegistry config) {
|
||||
config.setApplicationDestinationPrefixes("/app"); // <2>
|
||||
config.enableSimpleBroker("/topic", "/queue"); // <3>
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
<1> `/portfolio` is the HTTP URL for the endpoint to which a WebSocket (or SockJS)
|
||||
client needs to connect for the WebSocket handshake.
|
||||
<2> STOMP messages whose destination header begins with `/app` are routed to
|
||||
`@MessageMapping` methods in `@Controller` classes.
|
||||
<3> Use the built-in message broker for subscriptions and broadcasting and
|
||||
route messages whose destination header begins with `/topic` or `/queue` to the broker.
|
||||
|
||||
|
||||
The following example shows the XML configuration equivalent of the preceding example:
|
||||
|
||||
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
||||
----
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:websocket="http://www.springframework.org/schema/websocket"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans
|
||||
https://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/websocket
|
||||
https://www.springframework.org/schema/websocket/spring-websocket.xsd">
|
||||
|
||||
<websocket:message-broker application-destination-prefix="/app">
|
||||
<websocket:stomp-endpoint path="/portfolio" />
|
||||
<websocket:simple-broker prefix="/topic, /queue"/>
|
||||
</websocket:message-broker>
|
||||
|
||||
</beans>
|
||||
----
|
||||
include-code::./WebSocketConfiguration[tag=snippet,indent=0]
|
||||
|
||||
NOTE: For the built-in simple broker, the `/topic` and `/queue` prefixes do not have any special
|
||||
meaning. They are merely a convention to differentiate between pub-sub versus point-to-point
|
||||
|
||||
@@ -36,27 +36,7 @@ connectivity is lost, to the same host and port. If you wish to supply multiple
|
||||
on each attempt to connect, you can configure a supplier of addresses, instead of a
|
||||
fixed host and port. The following example shows how to do that:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
@Configuration
|
||||
@EnableWebSocketMessageBroker
|
||||
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
|
||||
|
||||
// ...
|
||||
|
||||
@Override
|
||||
public void configureMessageBroker(MessageBrokerRegistry registry) {
|
||||
registry.enableStompBrokerRelay("/queue/", "/topic/").setTcpClient(createTcpClient());
|
||||
registry.setApplicationDestinationPrefixes("/app");
|
||||
}
|
||||
|
||||
private ReactorNettyTcpClient<byte[]> createTcpClient() {
|
||||
return new ReactorNettyTcpClient<>(
|
||||
client -> client.addressSupplier(() -> ... ),
|
||||
new StompReactorNettyCodec());
|
||||
}
|
||||
}
|
||||
----
|
||||
include-code::./WebSocketConfiguration[tag=snippet,indent=0]
|
||||
|
||||
You can also configure the STOMP broker relay with a `virtualHost` property.
|
||||
The value of this property is set as the `host` header of every `CONNECT` frame
|
||||
|
||||
@@ -15,48 +15,7 @@ and run it with STOMP support enabled. Then you can enable the STOMP broker rela
|
||||
|
||||
The following example configuration enables a full-featured broker:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
@Configuration
|
||||
@EnableWebSocketMessageBroker
|
||||
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
|
||||
|
||||
@Override
|
||||
public void registerStompEndpoints(StompEndpointRegistry registry) {
|
||||
registry.addEndpoint("/portfolio").withSockJS();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configureMessageBroker(MessageBrokerRegistry registry) {
|
||||
registry.enableStompBrokerRelay("/topic", "/queue");
|
||||
registry.setApplicationDestinationPrefixes("/app");
|
||||
}
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
The following example shows the XML configuration equivalent of the preceding example:
|
||||
|
||||
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
||||
----
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:websocket="http://www.springframework.org/schema/websocket"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans
|
||||
https://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/websocket
|
||||
https://www.springframework.org/schema/websocket/spring-websocket.xsd">
|
||||
|
||||
<websocket:message-broker application-destination-prefix="/app">
|
||||
<websocket:stomp-endpoint path="/portfolio" />
|
||||
<websocket:sockjs/>
|
||||
</websocket:stomp-endpoint>
|
||||
<websocket:stomp-broker-relay prefix="/topic,/queue" />
|
||||
</websocket:message-broker>
|
||||
|
||||
</beans>
|
||||
----
|
||||
include-code::./WebSocketConfiguration[tag=snippet,indent=0]
|
||||
|
||||
The STOMP broker relay in the preceding configuration is a Spring
|
||||
{spring-framework-api}/messaging/MessageHandler.html[`MessageHandler`]
|
||||
|
||||
@@ -17,29 +17,4 @@ declared in the built-in WebSocket configuration, however, you'll' need `@Lazy`
|
||||
a cycle between the built-in WebSocket configuration and your
|
||||
`WebSocketMessageBrokerConfigurer`. For example:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
@Configuration
|
||||
@EnableWebSocketMessageBroker
|
||||
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
|
||||
|
||||
private TaskScheduler messageBrokerTaskScheduler;
|
||||
|
||||
@Autowired
|
||||
public void setMessageBrokerTaskScheduler(@Lazy TaskScheduler taskScheduler) {
|
||||
this.messageBrokerTaskScheduler = taskScheduler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configureMessageBroker(MessageBrokerRegistry registry) {
|
||||
registry.enableSimpleBroker("/queue/", "/topic/")
|
||||
.setHeartbeatValue(new long[] {10000, 20000})
|
||||
.setTaskScheduler(this.messageBrokerTaskScheduler);
|
||||
|
||||
// ...
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
|
||||
|
||||
include-code::./WebSocketConfiguration[tag=snippet,indent=0]
|
||||
|
||||
@@ -6,35 +6,12 @@ of a STOMP connection but not for every client message. Applications can also re
|
||||
`ChannelInterceptor` to intercept any message and in any part of the processing chain.
|
||||
The following example shows how to intercept inbound messages from clients:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
@Configuration
|
||||
@EnableWebSocketMessageBroker
|
||||
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
|
||||
|
||||
@Override
|
||||
public void configureClientInboundChannel(ChannelRegistration registration) {
|
||||
registration.interceptors(new MyChannelInterceptor());
|
||||
}
|
||||
}
|
||||
----
|
||||
include-code::./WebSocketConfiguration[tag=snippet,indent=0]
|
||||
|
||||
A custom `ChannelInterceptor` can use `StompHeaderAccessor` or `SimpMessageHeaderAccessor`
|
||||
to access information about the message, as the following example shows:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
public class MyChannelInterceptor implements ChannelInterceptor {
|
||||
|
||||
@Override
|
||||
public Message<?> preSend(Message<?> message, MessageChannel channel) {
|
||||
StompHeaderAccessor accessor = StompHeaderAccessor.wrap(message);
|
||||
StompCommand command = accessor.getStompCommand();
|
||||
// ...
|
||||
return message;
|
||||
}
|
||||
}
|
||||
----
|
||||
include-code::./MyChannelInterceptor[tag=snippet,indent=0]
|
||||
|
||||
Applications can also implement `ExecutorChannelInterceptor`, which is a sub-interface
|
||||
of `ChannelInterceptor` with callbacks in the thread in which the messages are handled.
|
||||
|
||||
@@ -60,33 +60,9 @@ to broadcast to subscribed clients.
|
||||
|
||||
We can trace the flow through a simple example. Consider the following example, which sets up a server:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
@Configuration
|
||||
@EnableWebSocketMessageBroker
|
||||
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
|
||||
include-code::./WebSocketConfiguration[tag=snippet,indent=0]
|
||||
|
||||
@Override
|
||||
public void registerStompEndpoints(StompEndpointRegistry registry) {
|
||||
registry.addEndpoint("/portfolio");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configureMessageBroker(MessageBrokerRegistry registry) {
|
||||
registry.setApplicationDestinationPrefixes("/app");
|
||||
registry.enableSimpleBroker("/topic");
|
||||
}
|
||||
}
|
||||
|
||||
@Controller
|
||||
public class GreetingController {
|
||||
|
||||
@MessageMapping("/greeting")
|
||||
public String handle(String greeting) {
|
||||
return "[" + getTimestamp() + ": " + greeting;
|
||||
}
|
||||
}
|
||||
----
|
||||
include-code::./GreetingController[tag=snippet,indent=0]
|
||||
|
||||
The preceding example supports the following flow:
|
||||
|
||||
|
||||
@@ -8,40 +8,7 @@ not match the exact order of publication.
|
||||
|
||||
To enable ordered publishing, set the `setPreservePublishOrder` flag as follows:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
@Configuration
|
||||
@EnableWebSocketMessageBroker
|
||||
public class MyConfig implements WebSocketMessageBrokerConfigurer {
|
||||
|
||||
@Override
|
||||
protected void configureMessageBroker(MessageBrokerRegistry registry) {
|
||||
// ...
|
||||
registry.setPreservePublishOrder(true);
|
||||
}
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
The following example shows the XML configuration equivalent of the preceding example:
|
||||
|
||||
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
||||
----
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:websocket="http://www.springframework.org/schema/websocket"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans
|
||||
https://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/websocket
|
||||
https://www.springframework.org/schema/websocket/spring-websocket.xsd">
|
||||
|
||||
<websocket:message-broker preserve-publish-order="true">
|
||||
<!-- ... -->
|
||||
</websocket:message-broker>
|
||||
|
||||
</beans>
|
||||
----
|
||||
include-code::./PublishOrderWebSocketConfiguration[tag=snippet,indent=0]
|
||||
|
||||
When the flag is set, messages within the same client session are published to the
|
||||
`clientOutboundChannel` one at a time, so that the order of publication is guaranteed.
|
||||
@@ -54,15 +21,4 @@ of handling may not match the exact order in which they were received.
|
||||
|
||||
To enable ordered publishing, set the `setPreserveReceiveOrder` flag as follows:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
@Configuration
|
||||
@EnableWebSocketMessageBroker
|
||||
public class MyConfig implements WebSocketMessageBrokerConfigurer {
|
||||
|
||||
@Override
|
||||
public void registerStompEndpoints(StompEndpointRegistry registry) {
|
||||
registry.setPreserveReceiveOrder(true);
|
||||
}
|
||||
}
|
||||
----
|
||||
include-code::./ReceiveOrderWebSocketConfiguration[tag=snippet,indent=0]
|
||||
|
||||
@@ -10,43 +10,9 @@ under the WebSocket section.
|
||||
|
||||
For Jetty WebSocket servers, customize the `JettyRequestUpgradeStrategy` as follows:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
@Configuration
|
||||
@EnableWebSocketMessageBroker
|
||||
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
|
||||
|
||||
@Override
|
||||
public void registerStompEndpoints(StompEndpointRegistry registry) {
|
||||
registry.addEndpoint("/portfolio").setHandshakeHandler(handshakeHandler());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DefaultHandshakeHandler handshakeHandler() {
|
||||
JettyRequestUpgradeStrategy strategy = new JettyRequestUpgradeStrategy();
|
||||
strategy.addWebSocketConfigurer(configurable -> {
|
||||
policy.setInputBufferSize(4 * 8192);
|
||||
policy.setIdleTimeout(600000);
|
||||
});
|
||||
return new DefaultHandshakeHandler(strategy);
|
||||
}
|
||||
}
|
||||
----
|
||||
include-code::./JettyWebSocketConfiguration[tag=snippet,indent=0]
|
||||
|
||||
In addition to WebSocket server properties, there are also STOMP WebSocket transport properties
|
||||
to customize as follows:
|
||||
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
@Configuration
|
||||
@EnableWebSocketMessageBroker
|
||||
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
|
||||
|
||||
@Override
|
||||
public void configureWebSocketTransport(WebSocketTransportRegistration registry) {
|
||||
registry.setMessageSizeLimit(4 * 8192);
|
||||
registry.setTimeToFirstMessage(30000);
|
||||
}
|
||||
|
||||
}
|
||||
----
|
||||
include-code::./WebSocketConfiguration[tag=snippet,indent=0]
|
||||
|
||||
Reference in New Issue
Block a user