diff --git a/framework-docs/framework-docs.gradle b/framework-docs/framework-docs.gradle
index 374e267096..c17b798f3f 100644
--- a/framework-docs/framework-docs.gradle
+++ b/framework-docs/framework-docs.gradle
@@ -66,6 +66,7 @@ dependencies {
api(project(":spring-webmvc"))
api(project(":spring-context-support"))
api(project(":spring-aspects"))
+ api(project(":spring-websocket"))
api("org.jetbrains.kotlin:kotlin-stdlib")
api("jakarta.jms:jakarta.jms-api")
@@ -76,6 +77,7 @@ dependencies {
api("com.fasterxml.jackson.module:jackson-module-parameter-names")
api("jakarta.validation:jakarta.validation-api")
api("org.aspectj:aspectjweaver")
+ api("io.projectreactor.netty:reactor-netty-http")
implementation(project(":spring-core-test"))
implementation("org.assertj:assertj-core")
diff --git a/framework-docs/modules/ROOT/pages/web/websocket/fallback.adoc b/framework-docs/modules/ROOT/pages/web/websocket/fallback.adoc
index d929c7f985..cafe41a814 100644
--- a/framework-docs/modules/ROOT/pages/web/websocket/fallback.adoc
+++ b/framework-docs/modules/ROOT/pages/web/websocket/fallback.adoc
@@ -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"]
-----
-
-
-
-
-
-
-
-
-
-
-----
+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
diff --git a/framework-docs/modules/ROOT/pages/web/websocket/server.adoc b/framework-docs/modules/ROOT/pages/web/websocket/server.adoc
index 30d18ba93c..5d5bbf5fa6 100644
--- a/framework-docs/modules/ROOT/pages/web/websocket/server.adoc
+++ b/framework-docs/modules/ROOT/pages/web/websocket/server.adoc
@@ -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"]
-----
-
-
-
-
-
-
-
-
-
-----
+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"]
-----
-
-
-
-
-
-
-
-
-
-
-
-
-----
+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"]
-----
-
-
-
-
-
-
-
-
-----
+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"]
-----
-
-
-
-
-
-
-
-
-
-----
-
-
-
-
+include-code::./WebSocketConfiguration[tag=snippet,indent=0]
diff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/authentication-token-based.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/authentication-token-based.adoc
index 03745ca29b..b65811e74b 100644
--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/authentication-token-based.adoc
+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/authentication-token-based.adoc
@@ -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
diff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/configuration-performance.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/configuration-performance.adoc
index 045d36398b..cc5df94802 100644
--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/configuration-performance.adoc
+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/configuration-performance.adoc
@@ -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"]
-----
-
-
-
-
-
-
-
-
-----
+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"]
-----
-
-
-
-
-
-
-
-
-----
+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.
diff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/destination-separator.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/destination-separator.adoc
index 866b6d81e0..0c81e2c2b8 100644
--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/destination-separator.adoc
+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/destination-separator.adoc
@@ -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"]
-----
-
-
-
-
-
-
-
-
-
-
-
-
-----
+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`.
diff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc
index 4330439843..4301ba9708 100644
--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc
+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/enable.adoc
@@ -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"]
-----
-
-
-
-
-
-
-
-
-----
+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
diff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay-configure.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay-configure.adoc
index 853732b600..f13d532367 100644
--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay-configure.adoc
+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay-configure.adoc
@@ -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 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
diff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay.adoc
index 8a59bd83f9..fd0ddcec22 100644
--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay.adoc
+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-broker-relay.adoc
@@ -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"]
-----
-
-
-
-
-
-
-
-
-
-
-----
+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`]
diff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-simple-broker.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-simple-broker.adoc
index 5be3fdb6ae..51ae36f771 100644
--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-simple-broker.adoc
+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/handle-simple-broker.adoc
@@ -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]
diff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/interceptors.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/interceptors.adoc
index 7a21a1b8d4..9bdab98351 100644
--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/interceptors.adoc
+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/interceptors.adoc
@@ -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.
diff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/message-flow.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/message-flow.adoc
index 1c4e3adb52..aee0cd9adc 100644
--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/message-flow.adoc
+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/message-flow.adoc
@@ -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:
diff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/ordered-messages.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/ordered-messages.adoc
index 89e60da926..a5d5f82f3a 100644
--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/ordered-messages.adoc
+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/ordered-messages.adoc
@@ -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"]
-----
-
-
-
-
-
-
-
-----
+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]
diff --git a/framework-docs/modules/ROOT/pages/web/websocket/stomp/server-config.adoc b/framework-docs/modules/ROOT/pages/web/websocket/stomp/server-config.adoc
index 7608bb8635..5903c07051 100644
--- a/framework-docs/modules/ROOT/pages/web/websocket/stomp/server-config.adoc
+++ b/framework-docs/modules/ROOT/pages/web/websocket/stomp/server-config.adoc
@@ -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]
diff --git a/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompauthenticationtokenbased/WebSocketConfiguration.java b/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompauthenticationtokenbased/WebSocketConfiguration.java
new file mode 100644
index 0000000000..2fb295375b
--- /dev/null
+++ b/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompauthenticationtokenbased/WebSocketConfiguration.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.docs.web.websocket.stomp.websocketstompauthenticationtokenbased;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.messaging.Message;
+import org.springframework.messaging.MessageChannel;
+import org.springframework.messaging.simp.config.ChannelRegistration;
+import org.springframework.messaging.simp.stomp.StompCommand;
+import org.springframework.messaging.simp.stomp.StompHeaderAccessor;
+import org.springframework.messaging.support.ChannelInterceptor;
+import org.springframework.messaging.support.MessageHeaderAccessor;
+import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
+import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
+
+// tag::snippet[]
+@Configuration
+@EnableWebSocketMessageBroker
+public class WebSocketConfiguration 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())) {
+ // Access authentication header(s) and invoke accessor.setUser(user)
+ }
+ return message;
+ }
+ });
+ }
+}
+// end::snippet[]
diff --git a/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompconfigurationperformance/MessageSizeLimitWebSocketConfiguration.java b/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompconfigurationperformance/MessageSizeLimitWebSocketConfiguration.java
new file mode 100644
index 0000000000..303e245f24
--- /dev/null
+++ b/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompconfigurationperformance/MessageSizeLimitWebSocketConfiguration.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.docs.web.websocket.stomp.websocketstompconfigurationperformance;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.messaging.simp.config.MessageBrokerRegistry;
+import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
+import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
+import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
+import org.springframework.web.socket.config.annotation.WebSocketTransportRegistration;
+
+// tag::snippet[]
+@Configuration
+@EnableWebSocketMessageBroker
+public class MessageSizeLimitWebSocketConfiguration implements WebSocketMessageBrokerConfigurer {
+
+ @Override
+ public void configureWebSocketTransport(WebSocketTransportRegistration registration) {
+ registration.setMessageSizeLimit(128 * 1024);
+ }
+
+ // ...
+
+}
+// end::snippet[]
diff --git a/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompconfigurationperformance/WebSocketConfiguration.java b/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompconfigurationperformance/WebSocketConfiguration.java
new file mode 100644
index 0000000000..82d556dd59
--- /dev/null
+++ b/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompconfigurationperformance/WebSocketConfiguration.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.docs.web.websocket.stomp.websocketstompconfigurationperformance;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.messaging.simp.config.MessageBrokerRegistry;
+import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
+import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
+import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
+import org.springframework.web.socket.config.annotation.WebSocketTransportRegistration;
+
+// tag::snippet[]
+@Configuration
+@EnableWebSocketMessageBroker
+public class WebSocketConfiguration implements WebSocketMessageBrokerConfigurer {
+
+ @Override
+ public void configureWebSocketTransport(WebSocketTransportRegistration registration) {
+ registration.setSendTimeLimit(15 * 1000).setSendBufferSizeLimit(512 * 1024);
+ }
+
+ // ...
+
+}
+// end::snippet[]
diff --git a/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompdestinationseparator/RedController.java b/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompdestinationseparator/RedController.java
new file mode 100644
index 0000000000..70f6ce8089
--- /dev/null
+++ b/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompdestinationseparator/RedController.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.docs.web.websocket.stomp.websocketstompdestinationseparator;
+
+import org.springframework.messaging.handler.annotation.DestinationVariable;
+import org.springframework.messaging.handler.annotation.MessageMapping;
+import org.springframework.stereotype.Controller;
+
+// tag::snippet[]
+@Controller
+@MessageMapping("red")
+public class RedController {
+
+ @MessageMapping("blue.{green}")
+ public void handleGreen(@DestinationVariable String green) {
+ // ...
+ }
+}
+// end::snippet[]
diff --git a/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompdestinationseparator/WebSocketConfiguration.java b/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompdestinationseparator/WebSocketConfiguration.java
new file mode 100644
index 0000000000..269f61bb80
--- /dev/null
+++ b/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompdestinationseparator/WebSocketConfiguration.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.docs.web.websocket.stomp.websocketstompdestinationseparator;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.messaging.simp.config.MessageBrokerRegistry;
+import org.springframework.util.AntPathMatcher;
+import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
+import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
+
+// tag::snippet[]
+@Configuration
+@EnableWebSocketMessageBroker
+public class WebSocketConfiguration implements WebSocketMessageBrokerConfigurer {
+
+ // ...
+
+ @Override
+ public void configureMessageBroker(MessageBrokerRegistry registry) {
+ registry.setPathMatcher(new AntPathMatcher("."));
+ registry.enableStompBrokerRelay("/queue", "/topic");
+ registry.setApplicationDestinationPrefixes("/app");
+ }
+}
+// end::snippet[]
diff --git a/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompenable/WebSocketConfiguration.java b/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompenable/WebSocketConfiguration.java
new file mode 100644
index 0000000000..0b282736aa
--- /dev/null
+++ b/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompenable/WebSocketConfiguration.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.docs.web.websocket.stomp.websocketstompenable;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.messaging.simp.config.MessageBrokerRegistry;
+import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
+import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
+import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
+
+// tag::snippet[]
+@Configuration
+@EnableWebSocketMessageBroker
+public class WebSocketConfiguration implements WebSocketMessageBrokerConfigurer {
+
+ @Override
+ public void registerStompEndpoints(StompEndpointRegistry registry) {
+ // /portfolio is the HTTP URL for the endpoint to which a WebSocket (or SockJS)
+ // client needs to connect for the WebSocket handshake
+ registry.addEndpoint("/portfolio");
+ }
+
+ @Override
+ public void configureMessageBroker(MessageBrokerRegistry config) {
+ // STOMP messages whose destination header begins with /app are routed to
+ // @MessageMapping methods in @Controller classes
+ config.setApplicationDestinationPrefixes("/app");
+ // Use the built-in message broker for subscriptions and broadcasting and
+ // route messages whose destination header begins with /topic or /queue to the broker
+ config.enableSimpleBroker("/topic", "/queue");
+ }
+}
+// end::snippet[]
diff --git a/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstomphandlebrokerrelay/WebSocketConfiguration.java b/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstomphandlebrokerrelay/WebSocketConfiguration.java
new file mode 100644
index 0000000000..20ddf32694
--- /dev/null
+++ b/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstomphandlebrokerrelay/WebSocketConfiguration.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.docs.web.websocket.stomp.websocketstomphandlebrokerrelay;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.messaging.simp.config.MessageBrokerRegistry;
+import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
+import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
+import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
+
+// tag::snippet[]
+@Configuration
+@EnableWebSocketMessageBroker
+public class WebSocketConfiguration 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");
+ }
+
+}
+// end::snippet[]
diff --git a/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstomphandlebrokerrelayconfigure/WebSocketConfiguration.java b/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstomphandlebrokerrelayconfigure/WebSocketConfiguration.java
new file mode 100644
index 0000000000..926da7d780
--- /dev/null
+++ b/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstomphandlebrokerrelayconfigure/WebSocketConfiguration.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.docs.web.websocket.stomp.websocketstomphandlebrokerrelayconfigure;
+
+import java.net.InetSocketAddress;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.messaging.simp.config.MessageBrokerRegistry;
+import org.springframework.messaging.simp.stomp.StompReactorNettyCodec;
+import org.springframework.messaging.tcp.reactor.ReactorNettyTcpClient;
+import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
+import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
+import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
+
+// tag::snippet[]
+@Configuration
+@EnableWebSocketMessageBroker
+public class WebSocketConfiguration implements WebSocketMessageBrokerConfigurer {
+
+ // ...
+
+ @Override
+ public void configureMessageBroker(MessageBrokerRegistry registry) {
+ registry.enableStompBrokerRelay("/queue/", "/topic/").setTcpClient(createTcpClient());
+ registry.setApplicationDestinationPrefixes("/app");
+ }
+
+ private ReactorNettyTcpClient createTcpClient() {
+ return new ReactorNettyTcpClient<>(
+ client -> client.addressSupplier(() -> new InetSocketAddress(0)),
+ new StompReactorNettyCodec());
+ }
+}
+// end::snippet[]
diff --git a/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstomphandlesimplebroker/WebSocketConfiguration.java b/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstomphandlesimplebroker/WebSocketConfiguration.java
new file mode 100644
index 0000000000..b6518257ce
--- /dev/null
+++ b/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstomphandlesimplebroker/WebSocketConfiguration.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.docs.web.websocket.stomp.websocketstomphandlesimplebroker;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.messaging.simp.config.MessageBrokerRegistry;
+import org.springframework.scheduling.TaskScheduler;
+import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
+import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
+import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
+
+// tag::snippet[]
+@Configuration
+@EnableWebSocketMessageBroker
+public class WebSocketConfiguration 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);
+
+ // ...
+ }
+}
+// end::snippet[]
diff --git a/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompinterceptors/MyChannelInterceptor.java b/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompinterceptors/MyChannelInterceptor.java
new file mode 100644
index 0000000000..721d631301
--- /dev/null
+++ b/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompinterceptors/MyChannelInterceptor.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.docs.web.websocket.stomp.websocketstompinterceptors;
+
+import org.springframework.messaging.Message;
+import org.springframework.messaging.MessageChannel;
+import org.springframework.messaging.simp.stomp.StompCommand;
+import org.springframework.messaging.simp.stomp.StompHeaderAccessor;
+import org.springframework.messaging.support.ChannelInterceptor;
+
+// tag::snippet[]
+public class MyChannelInterceptor implements ChannelInterceptor {
+
+ @Override
+ public Message> preSend(Message> message, MessageChannel channel) {
+ StompHeaderAccessor accessor = StompHeaderAccessor.wrap(message);
+ StompCommand command = accessor.getCommand();
+ // ...
+ return message;
+ }
+}
+// end::snippet[]
diff --git a/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompinterceptors/WebSocketConfiguration.java b/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompinterceptors/WebSocketConfiguration.java
new file mode 100644
index 0000000000..31082f7991
--- /dev/null
+++ b/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompinterceptors/WebSocketConfiguration.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.docs.web.websocket.stomp.websocketstompinterceptors;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.messaging.simp.config.ChannelRegistration;
+import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
+import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
+
+// tag::snippet[]
+@Configuration
+@EnableWebSocketMessageBroker
+public class WebSocketConfiguration implements WebSocketMessageBrokerConfigurer {
+
+ @Override
+ public void configureClientInboundChannel(ChannelRegistration registration) {
+ registration.interceptors(new MyChannelInterceptor());
+ }
+}
+// end::snippet[]
diff --git a/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompmessageflow/GreetingController.java b/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompmessageflow/GreetingController.java
new file mode 100644
index 0000000000..9f8302ac11
--- /dev/null
+++ b/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompmessageflow/GreetingController.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.docs.web.websocket.stomp.websocketstompmessageflow;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.messaging.handler.annotation.MessageMapping;
+import org.springframework.messaging.simp.config.MessageBrokerRegistry;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
+import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
+import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
+
+// tag::snippet[]
+@Controller
+public class GreetingController {
+
+ @MessageMapping("/greeting")
+ public String handle(String greeting) {
+ return "[" + getTimestamp() + ": " + greeting;
+ }
+
+ private String getTimestamp() {
+ return new SimpleDateFormat("MM/dd/yyyy h:mm:ss a").format(new Date());
+ }
+
+}
+// end::snippet[]
diff --git a/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompmessageflow/WebSocketConfiguration.java b/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompmessageflow/WebSocketConfiguration.java
new file mode 100644
index 0000000000..4198cc93e9
--- /dev/null
+++ b/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompmessageflow/WebSocketConfiguration.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.docs.web.websocket.stomp.websocketstompmessageflow;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.messaging.simp.config.MessageBrokerRegistry;
+import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
+import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
+import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
+
+// tag::snippet[]
+@Configuration
+@EnableWebSocketMessageBroker
+public class WebSocketConfiguration implements WebSocketMessageBrokerConfigurer {
+
+ @Override
+ public void registerStompEndpoints(StompEndpointRegistry registry) {
+ registry.addEndpoint("/portfolio");
+ }
+
+ @Override
+ public void configureMessageBroker(MessageBrokerRegistry registry) {
+ registry.setApplicationDestinationPrefixes("/app");
+ registry.enableSimpleBroker("/topic");
+ }
+}
+// end::snippet[]
diff --git a/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstomporderedmessages/PublishOrderWebSocketConfiguration.java b/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstomporderedmessages/PublishOrderWebSocketConfiguration.java
new file mode 100644
index 0000000000..527d2bb7ba
--- /dev/null
+++ b/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstomporderedmessages/PublishOrderWebSocketConfiguration.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.docs.web.websocket.stomp.websocketstomporderedmessages;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.messaging.simp.config.MessageBrokerRegistry;
+import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
+import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
+
+// tag::snippet[]
+@Configuration
+@EnableWebSocketMessageBroker
+public class PublishOrderWebSocketConfiguration implements WebSocketMessageBrokerConfigurer {
+
+ @Override
+ public void configureMessageBroker(MessageBrokerRegistry registry) {
+ // ...
+ registry.setPreservePublishOrder(true);
+ }
+
+}
+// end::snippet[]
diff --git a/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstomporderedmessages/ReceiveOrderWebSocketConfiguration.java b/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstomporderedmessages/ReceiveOrderWebSocketConfiguration.java
new file mode 100644
index 0000000000..9f787007bf
--- /dev/null
+++ b/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstomporderedmessages/ReceiveOrderWebSocketConfiguration.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.docs.web.websocket.stomp.websocketstomporderedmessages;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.messaging.simp.config.MessageBrokerRegistry;
+import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
+import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
+import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
+
+// tag::snippet[]
+@Configuration
+@EnableWebSocketMessageBroker
+public class ReceiveOrderWebSocketConfiguration implements WebSocketMessageBrokerConfigurer {
+
+ @Override
+ public void registerStompEndpoints(StompEndpointRegistry registry) {
+ registry.setPreserveReceiveOrder(true);
+ }
+}
+// end::snippet[]
diff --git a/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompserverconfig/JettyWebSocketConfiguration.java b/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompserverconfig/JettyWebSocketConfiguration.java
new file mode 100644
index 0000000000..78e4c99773
--- /dev/null
+++ b/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompserverconfig/JettyWebSocketConfiguration.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.docs.web.websocket.stomp.websocketstompserverconfig;
+
+import java.time.Duration;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
+import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
+import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
+import org.springframework.web.socket.server.jetty.JettyRequestUpgradeStrategy;
+import org.springframework.web.socket.server.support.DefaultHandshakeHandler;
+
+// tag::snippet[]
+@Configuration
+@EnableWebSocketMessageBroker
+public class JettyWebSocketConfiguration implements WebSocketMessageBrokerConfigurer {
+
+ @Override
+ public void registerStompEndpoints(StompEndpointRegistry registry) {
+ registry.addEndpoint("/portfolio").setHandshakeHandler(handshakeHandler());
+ }
+
+ @Bean
+ public DefaultHandshakeHandler handshakeHandler() {
+ JettyRequestUpgradeStrategy strategy = new JettyRequestUpgradeStrategy();
+ strategy.addWebSocketConfigurer(configurable -> {
+ configurable.setInputBufferSize(4 * 8192);
+ configurable.setIdleTimeout(Duration.ofSeconds(600));
+ });
+ return new DefaultHandshakeHandler(strategy);
+ }
+}
+// end::snippet[]
diff --git a/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompserverconfig/WebSocketConfiguration.java b/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompserverconfig/WebSocketConfiguration.java
new file mode 100644
index 0000000000..b43079e82b
--- /dev/null
+++ b/framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompserverconfig/WebSocketConfiguration.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.docs.web.websocket.stomp.websocketstompserverconfig;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
+import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
+import org.springframework.web.socket.config.annotation.WebSocketTransportRegistration;
+
+// tag::snippet[]
+@Configuration
+@EnableWebSocketMessageBroker
+public class WebSocketConfiguration implements WebSocketMessageBrokerConfigurer {
+
+ @Override
+ public void configureWebSocketTransport(WebSocketTransportRegistration registry) {
+ registry.setMessageSizeLimit(4 * 8192);
+ registry.setTimeToFirstMessage(30000);
+ }
+}
+// end::snippet[]
diff --git a/framework-docs/src/main/java/org/springframework/docs/web/websocket/websocketfallbacksockjsenable/WebSocketConfiguration.java b/framework-docs/src/main/java/org/springframework/docs/web/websocket/websocketfallbacksockjsenable/WebSocketConfiguration.java
new file mode 100644
index 0000000000..dde6939608
--- /dev/null
+++ b/framework-docs/src/main/java/org/springframework/docs/web/websocket/websocketfallbacksockjsenable/WebSocketConfiguration.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.docs.web.websocket.websocketfallbacksockjsenable;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.docs.web.websocket.websocketserverhandler.MyHandler;
+import org.springframework.web.socket.WebSocketHandler;
+import org.springframework.web.socket.config.annotation.EnableWebSocket;
+import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
+import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
+
+// tag::snippet[]
+@Configuration
+@EnableWebSocket
+public class WebSocketConfiguration implements WebSocketConfigurer {
+
+ @Override
+ public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
+ registry.addHandler(myHandler(), "/myHandler").withSockJS();
+ }
+
+ @Bean
+ public WebSocketHandler myHandler() {
+ return new MyHandler();
+ }
+
+}
+// end::snippet[]
diff --git a/framework-docs/src/main/java/org/springframework/docs/web/websocket/websocketserverallowedorigins/WebSocketConfiguration.java b/framework-docs/src/main/java/org/springframework/docs/web/websocket/websocketserverallowedorigins/WebSocketConfiguration.java
new file mode 100644
index 0000000000..632136a0da
--- /dev/null
+++ b/framework-docs/src/main/java/org/springframework/docs/web/websocket/websocketserverallowedorigins/WebSocketConfiguration.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.docs.web.websocket.websocketserverallowedorigins;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.docs.web.websocket.websocketserverhandler.MyHandler;
+import org.springframework.web.socket.WebSocketHandler;
+import org.springframework.web.socket.config.annotation.EnableWebSocket;
+import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
+import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
+
+// tag::snippet[]
+@Configuration
+@EnableWebSocket
+public class WebSocketConfiguration implements WebSocketConfigurer {
+
+ @Override
+ public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
+ registry.addHandler(myHandler(), "/myHandler").setAllowedOrigins("https://mydomain.com");
+ }
+
+ @Bean
+ public WebSocketHandler myHandler() {
+ return new MyHandler();
+ }
+}
+// end::snippet[]
diff --git a/framework-docs/src/main/java/org/springframework/docs/web/websocket/websocketserverhandler/MyHandler.java b/framework-docs/src/main/java/org/springframework/docs/web/websocket/websocketserverhandler/MyHandler.java
new file mode 100644
index 0000000000..ed4be8e7d7
--- /dev/null
+++ b/framework-docs/src/main/java/org/springframework/docs/web/websocket/websocketserverhandler/MyHandler.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.docs.web.websocket.websocketserverhandler;
+
+import org.springframework.web.socket.TextMessage;
+import org.springframework.web.socket.WebSocketSession;
+import org.springframework.web.socket.handler.TextWebSocketHandler;
+
+// tag::snippet[]
+public class MyHandler extends TextWebSocketHandler {
+
+ @Override
+ protected void handleTextMessage(WebSocketSession session, TextMessage message) {
+ // ...
+ }
+}
+// end::snippet[]
diff --git a/framework-docs/src/main/java/org/springframework/docs/web/websocket/websocketserverhandler/WebSocketConfiguration.java b/framework-docs/src/main/java/org/springframework/docs/web/websocket/websocketserverhandler/WebSocketConfiguration.java
new file mode 100644
index 0000000000..753a598eed
--- /dev/null
+++ b/framework-docs/src/main/java/org/springframework/docs/web/websocket/websocketserverhandler/WebSocketConfiguration.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.docs.web.websocket.websocketserverhandler;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.socket.WebSocketHandler;
+import org.springframework.web.socket.config.annotation.EnableWebSocket;
+import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
+import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
+
+// tag::snippet[]
+@Configuration
+@EnableWebSocket
+public class WebSocketConfiguration implements WebSocketConfigurer {
+
+ @Override
+ public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
+ registry.addHandler(myHandler(), "/myHandler");
+ }
+
+ @Bean
+ public WebSocketHandler myHandler() {
+ return new MyHandler();
+ }
+}
+// end::snippet[]
diff --git a/framework-docs/src/main/java/org/springframework/docs/web/websocket/websocketserverhandshake/WebSocketConfiguration.java b/framework-docs/src/main/java/org/springframework/docs/web/websocket/websocketserverhandshake/WebSocketConfiguration.java
new file mode 100644
index 0000000000..87b5d64325
--- /dev/null
+++ b/framework-docs/src/main/java/org/springframework/docs/web/websocket/websocketserverhandshake/WebSocketConfiguration.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.docs.web.websocket.websocketserverhandshake;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.docs.web.websocket.websocketserverhandler.MyHandler;
+import org.springframework.web.socket.config.annotation.EnableWebSocket;
+import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
+import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
+import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;
+
+// tag::snippet[]
+@Configuration
+@EnableWebSocket
+public class WebSocketConfiguration implements WebSocketConfigurer {
+
+ @Override
+ public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
+ registry.addHandler(new MyHandler(), "/myHandler")
+ .addInterceptors(new HttpSessionHandshakeInterceptor());
+ }
+
+}
+// end::snippet[]
diff --git a/framework-docs/src/main/java/org/springframework/docs/web/websocket/websocketserverruntimeconfiguration/JettyWebSocketConfiguration.java b/framework-docs/src/main/java/org/springframework/docs/web/websocket/websocketserverruntimeconfiguration/JettyWebSocketConfiguration.java
new file mode 100644
index 0000000000..07897a2a2d
--- /dev/null
+++ b/framework-docs/src/main/java/org/springframework/docs/web/websocket/websocketserverruntimeconfiguration/JettyWebSocketConfiguration.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.docs.web.websocket.websocketserverruntimeconfiguration;
+
+import java.time.Duration;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.socket.WebSocketHandler;
+import org.springframework.web.socket.config.annotation.EnableWebSocket;
+import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
+import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
+import org.springframework.web.socket.server.jetty.JettyRequestUpgradeStrategy;
+import org.springframework.web.socket.server.support.DefaultHandshakeHandler;
+
+// tag::snippet[]
+@Configuration
+@EnableWebSocket
+public class JettyWebSocketConfiguration implements WebSocketConfigurer {
+
+ @Override
+ public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
+ registry.addHandler(echoWebSocketHandler(), "/echo").setHandshakeHandler(handshakeHandler());
+ }
+
+ @Bean
+ public WebSocketHandler echoWebSocketHandler() {
+ return new MyEchoHandler();
+ }
+
+ @Bean
+ public DefaultHandshakeHandler handshakeHandler() {
+ JettyRequestUpgradeStrategy strategy = new JettyRequestUpgradeStrategy();
+ strategy.addWebSocketConfigurer(configurable -> {
+ configurable.setInputBufferSize(8192);
+ configurable.setIdleTimeout(Duration.ofSeconds(600));
+ });
+ return new DefaultHandshakeHandler(strategy);
+ }
+}
+// end::snippet[]
diff --git a/framework-docs/src/main/java/org/springframework/docs/web/websocket/websocketserverruntimeconfiguration/MyEchoHandler.java b/framework-docs/src/main/java/org/springframework/docs/web/websocket/websocketserverruntimeconfiguration/MyEchoHandler.java
new file mode 100644
index 0000000000..76f78d5e97
--- /dev/null
+++ b/framework-docs/src/main/java/org/springframework/docs/web/websocket/websocketserverruntimeconfiguration/MyEchoHandler.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.docs.web.websocket.websocketserverruntimeconfiguration;
+
+import org.springframework.web.socket.handler.AbstractWebSocketHandler;
+
+public class MyEchoHandler extends AbstractWebSocketHandler {
+}
diff --git a/framework-docs/src/main/java/org/springframework/docs/web/websocket/websocketserverruntimeconfiguration/WebSocketConfiguration.java b/framework-docs/src/main/java/org/springframework/docs/web/websocket/websocketserverruntimeconfiguration/WebSocketConfiguration.java
new file mode 100644
index 0000000000..95c74290c5
--- /dev/null
+++ b/framework-docs/src/main/java/org/springframework/docs/web/websocket/websocketserverruntimeconfiguration/WebSocketConfiguration.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.docs.web.websocket.websocketserverruntimeconfiguration;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.socket.server.standard.ServletServerContainerFactoryBean;
+
+// tag::snippet[]
+@Configuration
+public class WebSocketConfiguration {
+
+ @Bean
+ public ServletServerContainerFactoryBean createWebSocketContainer() {
+ ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
+ container.setMaxTextMessageBufferSize(8192);
+ container.setMaxBinaryMessageBufferSize(8192);
+ return container;
+ }
+}
+// end::snippet[]
diff --git a/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompauthenticationtokenbased/WebSocketConfiguration.kt b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompauthenticationtokenbased/WebSocketConfiguration.kt
new file mode 100644
index 0000000000..d03e7e0995
--- /dev/null
+++ b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompauthenticationtokenbased/WebSocketConfiguration.kt
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.docs.web.websocket.stomp.websocketstompauthenticationtokenbased
+
+import org.springframework.context.annotation.Configuration
+import org.springframework.messaging.Message
+import org.springframework.messaging.MessageChannel
+import org.springframework.messaging.simp.config.ChannelRegistration
+import org.springframework.messaging.simp.stomp.StompCommand
+import org.springframework.messaging.simp.stomp.StompHeaderAccessor
+import org.springframework.messaging.support.ChannelInterceptor
+import org.springframework.messaging.support.MessageHeaderAccessor
+import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker
+import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer
+
+// tag::snippet[]
+@Configuration
+@EnableWebSocketMessageBroker
+class WebSocketConfiguration : WebSocketMessageBrokerConfigurer {
+
+ override fun configureClientInboundChannel(registration: ChannelRegistration) {
+ registration.interceptors(object : ChannelInterceptor {
+ override fun preSend(message: Message<*>, channel: MessageChannel): Message<*> {
+ val accessor = MessageHeaderAccessor.getAccessor(message,
+ StompHeaderAccessor::class.java)
+ if (StompCommand.CONNECT == accessor!!.command) {
+ // Access authentication header(s) and invoke accessor.setUser(user)
+ }
+ return message
+ }
+ })
+ }
+}
+// end::snippet[]
diff --git a/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompconfigurationperformance/MessageSizeLimitWebSocketConfiguration.kt b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompconfigurationperformance/MessageSizeLimitWebSocketConfiguration.kt
new file mode 100644
index 0000000000..b8affe8c5e
--- /dev/null
+++ b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompconfigurationperformance/MessageSizeLimitWebSocketConfiguration.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.docs.web.websocket.stomp.websocketstompconfigurationperformance
+
+import org.springframework.context.annotation.Configuration
+import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker
+import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer
+import org.springframework.web.socket.config.annotation.WebSocketTransportRegistration
+
+// tag::snippet[]
+@Configuration
+@EnableWebSocketMessageBroker
+class MessageSizeLimitWebSocketConfiguration : WebSocketMessageBrokerConfigurer {
+
+ override fun configureWebSocketTransport(registration: WebSocketTransportRegistration) {
+ registration.setMessageSizeLimit(128 * 1024)
+ }
+
+ // ...
+}
+// end::snippet[]
diff --git a/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompconfigurationperformance/WebSocketConfiguration.kt b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompconfigurationperformance/WebSocketConfiguration.kt
new file mode 100644
index 0000000000..ecdd126a33
--- /dev/null
+++ b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompconfigurationperformance/WebSocketConfiguration.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.docs.web.websocket.stomp.websocketstompconfigurationperformance
+
+import org.springframework.context.annotation.Configuration
+import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker
+import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer
+import org.springframework.web.socket.config.annotation.WebSocketTransportRegistration
+
+// tag::snippet[]
+@Configuration
+@EnableWebSocketMessageBroker
+class WebSocketConfiguration : WebSocketMessageBrokerConfigurer {
+
+ override fun configureWebSocketTransport(registration: WebSocketTransportRegistration) {
+ registration.setSendTimeLimit(15 * 1000).setSendBufferSizeLimit(512 * 1024)
+ }
+
+ // ...
+}
+// end::snippet[]
\ No newline at end of file
diff --git a/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompdestinationseparator/RedController.kt b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompdestinationseparator/RedController.kt
new file mode 100644
index 0000000000..cb528a5ebc
--- /dev/null
+++ b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompdestinationseparator/RedController.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.docs.web.websocket.stomp.websocketstompdestinationseparator
+
+import org.springframework.messaging.handler.annotation.DestinationVariable
+import org.springframework.messaging.handler.annotation.MessageMapping
+import org.springframework.stereotype.Controller
+
+// tag::snippet[]
+@Controller
+@MessageMapping("red")
+class RedController {
+
+ @MessageMapping("blue.{green}")
+ fun handleGreen(@DestinationVariable green: String?) {
+ // ...
+ }
+}
+// end::snippet[]
diff --git a/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompdestinationseparator/WebSocketConfiguration.kt b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompdestinationseparator/WebSocketConfiguration.kt
new file mode 100644
index 0000000000..0e0502a650
--- /dev/null
+++ b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompdestinationseparator/WebSocketConfiguration.kt
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.docs.web.websocket.stomp.websocketstompdestinationseparator
+
+import org.springframework.context.annotation.Configuration
+import org.springframework.messaging.simp.config.MessageBrokerRegistry
+import org.springframework.util.AntPathMatcher
+import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker
+import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer
+
+// tag::snippet[]
+@Configuration
+@EnableWebSocketMessageBroker
+class WebSocketConfiguration : WebSocketMessageBrokerConfigurer {
+
+ // ...
+
+ override fun configureMessageBroker(registry: MessageBrokerRegistry) {
+ registry.setPathMatcher(AntPathMatcher("."))
+ registry.enableStompBrokerRelay("/queue", "/topic")
+ registry.setApplicationDestinationPrefixes("/app")
+ }
+}
+// end::snippet[]
\ No newline at end of file
diff --git a/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompenable/WebSocketConfiguration.kt b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompenable/WebSocketConfiguration.kt
new file mode 100644
index 0000000000..554d709621
--- /dev/null
+++ b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompenable/WebSocketConfiguration.kt
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.docs.web.websocket.stomp.websocketstompenable
+
+import org.springframework.context.annotation.Configuration
+import org.springframework.messaging.simp.config.MessageBrokerRegistry
+import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker
+import org.springframework.web.socket.config.annotation.StompEndpointRegistry
+import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer
+
+// tag::snippet[]
+@Configuration
+@EnableWebSocketMessageBroker
+class WebSocketConfiguration : WebSocketMessageBrokerConfigurer {
+
+ override fun registerStompEndpoints(registry: StompEndpointRegistry) {
+ // /portfolio is the HTTP URL for the endpoint to which a WebSocket (or SockJS)
+ // client needs to connect for the WebSocket handshake
+ registry.addEndpoint("/portfolio")
+ }
+
+ override fun configureMessageBroker(config: MessageBrokerRegistry) {
+ // STOMP messages whose destination header begins with /app are routed to
+ // @MessageMapping methods in @Controller classes
+ config.setApplicationDestinationPrefixes("/app")
+ // Use the built-in message broker for subscriptions and broadcasting and
+ // route messages whose destination header begins with /topic or /queue to the broker
+ config.enableSimpleBroker("/topic", "/queue")
+ }
+}
+// end::snippet[]
\ No newline at end of file
diff --git a/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstomphandlebrokerrelay/WebSocketConfiguration.kt b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstomphandlebrokerrelay/WebSocketConfiguration.kt
new file mode 100644
index 0000000000..aa3630b5c6
--- /dev/null
+++ b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstomphandlebrokerrelay/WebSocketConfiguration.kt
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.docs.web.websocket.stomp.websocketstomphandlebrokerrelay
+
+import org.springframework.context.annotation.Configuration
+import org.springframework.messaging.simp.config.MessageBrokerRegistry
+import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker
+import org.springframework.web.socket.config.annotation.StompEndpointRegistry
+import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer
+
+// tag::snippet[]
+@Configuration
+@EnableWebSocketMessageBroker
+class WebSocketConfiguration : WebSocketMessageBrokerConfigurer {
+
+ override fun registerStompEndpoints(registry: StompEndpointRegistry) {
+ registry.addEndpoint("/portfolio").withSockJS()
+ }
+
+ override fun configureMessageBroker(registry: MessageBrokerRegistry) {
+ registry.enableStompBrokerRelay("/topic", "/queue")
+ registry.setApplicationDestinationPrefixes("/app")
+ }
+}
+// end::snippet[]
\ No newline at end of file
diff --git a/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstomphandlebrokerrelayconfigure/WebSocketConfiguration.kt b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstomphandlebrokerrelayconfigure/WebSocketConfiguration.kt
new file mode 100644
index 0000000000..e051874aa0
--- /dev/null
+++ b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstomphandlebrokerrelayconfigure/WebSocketConfiguration.kt
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.docs.web.websocket.stomp.websocketstomphandlebrokerrelayconfigure
+
+import org.springframework.context.annotation.Configuration
+import org.springframework.messaging.simp.config.MessageBrokerRegistry
+import org.springframework.messaging.simp.stomp.StompReactorNettyCodec
+import org.springframework.messaging.tcp.reactor.ReactorNettyTcpClient
+import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker
+import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer
+import java.net.InetSocketAddress
+
+// tag::snippet[]
+@Configuration
+@EnableWebSocketMessageBroker
+class WebSocketConfiguration : WebSocketMessageBrokerConfigurer {
+
+ // ...
+
+ override fun configureMessageBroker(registry: MessageBrokerRegistry) {
+ registry.enableStompBrokerRelay("/queue/", "/topic/").setTcpClient(createTcpClient())
+ registry.setApplicationDestinationPrefixes("/app")
+ }
+
+ private fun createTcpClient(): ReactorNettyTcpClient {
+ return ReactorNettyTcpClient({ it.addressSupplier { InetSocketAddress(0) } }, StompReactorNettyCodec())
+ }
+}
+// end::snippet[]
\ No newline at end of file
diff --git a/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstomphandlesimplebroker/WebSocketConfiguration.kt b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstomphandlesimplebroker/WebSocketConfiguration.kt
new file mode 100644
index 0000000000..4602aaee20
--- /dev/null
+++ b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstomphandlesimplebroker/WebSocketConfiguration.kt
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.docs.web.websocket.stomp.websocketstomphandlesimplebroker
+
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.context.annotation.Configuration
+import org.springframework.context.annotation.Lazy
+import org.springframework.messaging.simp.config.MessageBrokerRegistry
+import org.springframework.scheduling.TaskScheduler
+import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker
+import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer
+
+// tag::snippet[]
+@Configuration
+@EnableWebSocketMessageBroker
+class WebSocketConfiguration : WebSocketMessageBrokerConfigurer {
+
+ private lateinit var messageBrokerTaskScheduler: TaskScheduler
+
+ @Autowired
+ fun setMessageBrokerTaskScheduler(@Lazy taskScheduler: TaskScheduler) {
+ this.messageBrokerTaskScheduler = taskScheduler
+ }
+
+ override fun configureMessageBroker(registry: MessageBrokerRegistry) {
+ registry.enableSimpleBroker("/queue/", "/topic/")
+ .setHeartbeatValue(longArrayOf(10000, 20000))
+ .setTaskScheduler(messageBrokerTaskScheduler)
+
+ // ...
+ }
+}
+// end::snippet[]
diff --git a/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompinterceptors/MyChannelInterceptor.kt b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompinterceptors/MyChannelInterceptor.kt
new file mode 100644
index 0000000000..11fd7dc30e
--- /dev/null
+++ b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompinterceptors/MyChannelInterceptor.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.docs.web.websocket.stomp.websocketstompinterceptors
+
+import org.springframework.messaging.Message
+import org.springframework.messaging.MessageChannel
+import org.springframework.messaging.simp.stomp.StompHeaderAccessor
+import org.springframework.messaging.support.ChannelInterceptor
+
+// tag::snippet[]
+class MyChannelInterceptor : ChannelInterceptor {
+
+ override fun preSend(message: Message<*>, channel: MessageChannel): Message<*> {
+ val accessor = StompHeaderAccessor.wrap(message)
+ val command = accessor.command
+ // ...
+ return message
+ }
+}
+// end::snippet[]
\ No newline at end of file
diff --git a/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompinterceptors/WebSocketConfiguration.kt b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompinterceptors/WebSocketConfiguration.kt
new file mode 100644
index 0000000000..2516b8d730
--- /dev/null
+++ b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompinterceptors/WebSocketConfiguration.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.docs.web.websocket.stomp.websocketstompinterceptors
+
+import org.springframework.context.annotation.Configuration
+import org.springframework.messaging.simp.config.ChannelRegistration
+import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker
+import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer
+
+// tag::snippet[]
+@Configuration
+@EnableWebSocketMessageBroker
+class WebSocketConfiguration : WebSocketMessageBrokerConfigurer {
+
+ override fun configureClientInboundChannel(registration: ChannelRegistration) {
+ registration.interceptors(MyChannelInterceptor())
+ }
+}
+// end::snippet[]
\ No newline at end of file
diff --git a/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompmessageflow/GreetingController.kt b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompmessageflow/GreetingController.kt
new file mode 100644
index 0000000000..ab24a3f16d
--- /dev/null
+++ b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompmessageflow/GreetingController.kt
@@ -0,0 +1,21 @@
+package org.springframework.docs.web.websocket.stomp.websocketstompmessageflow
+
+import org.springframework.messaging.handler.annotation.MessageMapping
+import org.springframework.stereotype.Controller
+import java.text.SimpleDateFormat
+import java.util.*
+
+// tag::snippet[]
+@Controller
+class GreetingController {
+
+ @MessageMapping("/greeting")
+ fun handle(greeting: String): String {
+ return "[${getTimestamp()}: $greeting"
+ }
+
+ private fun getTimestamp(): String {
+ return SimpleDateFormat("MM/dd/yyyy h:mm:ss a").format(Date())
+ }
+}
+// end::snippet[]
diff --git a/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompmessageflow/WebSocketConfiguration.kt b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompmessageflow/WebSocketConfiguration.kt
new file mode 100644
index 0000000000..e464312da1
--- /dev/null
+++ b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompmessageflow/WebSocketConfiguration.kt
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.docs.web.websocket.stomp.websocketstompmessageflow
+
+import org.springframework.context.annotation.Configuration
+import org.springframework.messaging.simp.config.MessageBrokerRegistry
+import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker
+import org.springframework.web.socket.config.annotation.StompEndpointRegistry
+import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer
+
+
+// tag::snippet[]
+@Configuration
+@EnableWebSocketMessageBroker
+class WebSocketConfiguration : WebSocketMessageBrokerConfigurer {
+ override fun registerStompEndpoints(registry: StompEndpointRegistry) {
+ registry.addEndpoint("/portfolio")
+ }
+
+ override fun configureMessageBroker(registry: MessageBrokerRegistry) {
+ registry.setApplicationDestinationPrefixes("/app")
+ registry.enableSimpleBroker("/topic")
+ }
+}
+// end::snippet[]
\ No newline at end of file
diff --git a/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstomporderedmessages/PublishOrderWebSocketConfiguration.kt b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstomporderedmessages/PublishOrderWebSocketConfiguration.kt
new file mode 100644
index 0000000000..74c6d508e6
--- /dev/null
+++ b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstomporderedmessages/PublishOrderWebSocketConfiguration.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.docs.web.websocket.stomp.websocketstomporderedmessages
+
+import org.springframework.context.annotation.Configuration
+import org.springframework.messaging.simp.config.MessageBrokerRegistry
+import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker
+import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer
+
+// tag::snippet[]
+@Configuration
+@EnableWebSocketMessageBroker
+class PublishOrderWebSocketConfiguration : WebSocketMessageBrokerConfigurer {
+
+ override fun configureMessageBroker(registry: MessageBrokerRegistry) {
+ // ...
+ registry.setPreservePublishOrder(true)
+ }
+}
+// end::snippet[]
\ No newline at end of file
diff --git a/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstomporderedmessages/ReceiveOrderWebSocketConfiguration.kt b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstomporderedmessages/ReceiveOrderWebSocketConfiguration.kt
new file mode 100644
index 0000000000..a5324bbe0b
--- /dev/null
+++ b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstomporderedmessages/ReceiveOrderWebSocketConfiguration.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.docs.web.websocket.stomp.websocketstomporderedmessages
+
+import org.springframework.context.annotation.Configuration
+import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker
+import org.springframework.web.socket.config.annotation.StompEndpointRegistry
+import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer
+
+// tag::snippet[]
+@Configuration
+@EnableWebSocketMessageBroker
+class ReceiveOrderWebSocketConfiguration : WebSocketMessageBrokerConfigurer {
+
+ override fun registerStompEndpoints(registry: StompEndpointRegistry) {
+ registry.setPreserveReceiveOrder(true)
+ }
+}
+// end::snippet[]
\ No newline at end of file
diff --git a/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompserverconfig/JettyWebSocketConfiguration.kt b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompserverconfig/JettyWebSocketConfiguration.kt
new file mode 100644
index 0000000000..333403de4f
--- /dev/null
+++ b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompserverconfig/JettyWebSocketConfiguration.kt
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.docs.web.websocket.stomp.websocketstompserverconfig
+
+import org.springframework.context.annotation.Bean
+import org.springframework.context.annotation.Configuration
+import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker
+import org.springframework.web.socket.config.annotation.StompEndpointRegistry
+import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer
+import org.springframework.web.socket.server.jetty.JettyRequestUpgradeStrategy
+import org.springframework.web.socket.server.support.DefaultHandshakeHandler
+import java.time.Duration
+import java.util.function.Consumer
+
+// tag::snippet[]
+@Configuration
+@EnableWebSocketMessageBroker
+class JettyWebSocketConfiguration : WebSocketMessageBrokerConfigurer {
+
+ override fun registerStompEndpoints(registry: StompEndpointRegistry) {
+ registry.addEndpoint("/portfolio").setHandshakeHandler(handshakeHandler())
+ }
+
+ @Bean
+ fun handshakeHandler(): DefaultHandshakeHandler {
+ val strategy = JettyRequestUpgradeStrategy()
+ strategy.addWebSocketConfigurer {
+ it.inputBufferSize = 4 * 8192
+ it.idleTimeout = Duration.ofSeconds(600)
+ }
+ return DefaultHandshakeHandler(strategy)
+ }
+}
+// end::snippet[]
diff --git a/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompserverconfig/WebSocketConfiguration.kt b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompserverconfig/WebSocketConfiguration.kt
new file mode 100644
index 0000000000..50b6916fe8
--- /dev/null
+++ b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompserverconfig/WebSocketConfiguration.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.docs.web.websocket.stomp.websocketstompserverconfig
+
+import org.springframework.context.annotation.Configuration
+import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker
+import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer
+import org.springframework.web.socket.config.annotation.WebSocketTransportRegistration
+
+// tag::snippet[]
+@Configuration
+@EnableWebSocketMessageBroker
+class WebSocketConfiguration : WebSocketMessageBrokerConfigurer {
+
+ override fun configureWebSocketTransport(registry: WebSocketTransportRegistration) {
+ registry.setMessageSizeLimit(4 * 8192)
+ registry.setTimeToFirstMessage(30000)
+ }
+}
+// end::snippet[]
diff --git a/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/websocketfallbacksockjsenable/WebSocketConfiguration.kt b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/websocketfallbacksockjsenable/WebSocketConfiguration.kt
new file mode 100644
index 0000000000..432e804488
--- /dev/null
+++ b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/websocketfallbacksockjsenable/WebSocketConfiguration.kt
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.docs.web.websocket.websocketfallbacksockjsenable
+
+import org.springframework.context.annotation.Bean
+import org.springframework.context.annotation.Configuration
+import org.springframework.docs.web.websocket.websocketserverhandler.MyHandler
+import org.springframework.web.socket.WebSocketHandler
+import org.springframework.web.socket.config.annotation.EnableWebSocket
+import org.springframework.web.socket.config.annotation.WebSocketConfigurer
+import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry
+
+// tag::snippet[]
+@Configuration
+@EnableWebSocket
+class WebSocketConfiguration : WebSocketConfigurer {
+ override fun registerWebSocketHandlers(registry: WebSocketHandlerRegistry) {
+ registry.addHandler(myHandler(), "/myHandler").withSockJS()
+ }
+
+ @Bean
+ fun myHandler(): WebSocketHandler {
+ return MyHandler()
+ }
+}
+// end::snippet[]
diff --git a/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/websocketserverallowedorigins/WebSocketConfiguration.kt b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/websocketserverallowedorigins/WebSocketConfiguration.kt
new file mode 100644
index 0000000000..79f80e690d
--- /dev/null
+++ b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/websocketserverallowedorigins/WebSocketConfiguration.kt
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.docs.web.websocket.websocketserverallowedorigins
+
+import org.springframework.context.annotation.Bean
+import org.springframework.context.annotation.Configuration
+import org.springframework.docs.web.websocket.websocketserverhandler.MyHandler
+import org.springframework.web.socket.WebSocketHandler
+import org.springframework.web.socket.config.annotation.EnableWebSocket
+import org.springframework.web.socket.config.annotation.WebSocketConfigurer
+import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry
+
+// tag::snippet[]
+@Configuration
+@EnableWebSocket
+class WebSocketConfiguration : WebSocketConfigurer {
+
+ override fun registerWebSocketHandlers(registry: WebSocketHandlerRegistry) {
+ registry.addHandler(myHandler(), "/myHandler").setAllowedOrigins("https://mydomain.com")
+ }
+
+ @Bean
+ fun myHandler(): WebSocketHandler {
+ return MyHandler()
+ }
+}
+// end::snippet[]
diff --git a/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/websocketserverhandler/MyHandler.kt b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/websocketserverhandler/MyHandler.kt
new file mode 100644
index 0000000000..38b53e01b6
--- /dev/null
+++ b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/websocketserverhandler/MyHandler.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.docs.web.websocket.websocketserverhandler
+
+import org.springframework.web.socket.TextMessage
+import org.springframework.web.socket.WebSocketSession
+import org.springframework.web.socket.handler.TextWebSocketHandler
+
+// tag::snippet[]
+class MyHandler : TextWebSocketHandler() {
+
+ override fun handleTextMessage(session: WebSocketSession, message: TextMessage) {
+ // ...
+ }
+}
+// end::snippet[]
diff --git a/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/websocketserverhandler/WebSocketConfiguration.kt b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/websocketserverhandler/WebSocketConfiguration.kt
new file mode 100644
index 0000000000..5217d325d1
--- /dev/null
+++ b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/websocketserverhandler/WebSocketConfiguration.kt
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.docs.web.websocket.websocketserverhandler
+
+import org.springframework.context.annotation.Bean
+import org.springframework.context.annotation.Configuration
+import org.springframework.web.socket.WebSocketHandler
+import org.springframework.web.socket.config.annotation.EnableWebSocket
+import org.springframework.web.socket.config.annotation.WebSocketConfigurer
+import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry
+
+// tag::snippet[]
+@Configuration
+@EnableWebSocket
+class WebSocketConfiguration : WebSocketConfigurer {
+
+ override fun registerWebSocketHandlers(registry: WebSocketHandlerRegistry) {
+ registry.addHandler(myHandler(), "/myHandler")
+ }
+
+ @Bean
+ fun myHandler(): WebSocketHandler {
+ return MyHandler()
+ }
+}
+// end::snippet[]
diff --git a/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/websocketserverhandshake/WebSocketConfiguration.kt b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/websocketserverhandshake/WebSocketConfiguration.kt
new file mode 100644
index 0000000000..fd6d5fd1c6
--- /dev/null
+++ b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/websocketserverhandshake/WebSocketConfiguration.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.docs.web.websocket.websocketserverhandshake
+
+import org.springframework.context.annotation.Configuration
+import org.springframework.docs.web.websocket.websocketserverhandler.MyHandler
+import org.springframework.web.socket.config.annotation.EnableWebSocket
+import org.springframework.web.socket.config.annotation.WebSocketConfigurer
+import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry
+import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor
+
+// tag::snippet[]
+@Configuration
+@EnableWebSocket
+class WebSocketConfiguration : WebSocketConfigurer {
+
+ override fun registerWebSocketHandlers(registry: WebSocketHandlerRegistry) {
+ registry.addHandler(MyHandler(), "/myHandler")
+ .addInterceptors(HttpSessionHandshakeInterceptor())
+ }
+}
+// end::snippet[]
diff --git a/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/websocketserverruntimeconfiguration/JettyWebSocketConfiguration.kt b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/websocketserverruntimeconfiguration/JettyWebSocketConfiguration.kt
new file mode 100644
index 0000000000..0c2faf491a
--- /dev/null
+++ b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/websocketserverruntimeconfiguration/JettyWebSocketConfiguration.kt
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.docs.web.websocket.websocketserverruntimeconfiguration
+
+import org.springframework.context.annotation.Bean
+import org.springframework.context.annotation.Configuration
+import org.springframework.web.socket.WebSocketHandler
+import org.springframework.web.socket.config.annotation.EnableWebSocket
+import org.springframework.web.socket.config.annotation.WebSocketConfigurer
+import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry
+import org.springframework.web.socket.server.jetty.JettyRequestUpgradeStrategy
+import org.springframework.web.socket.server.support.DefaultHandshakeHandler
+import java.time.Duration
+
+// tag::snippet[]
+@Configuration
+@EnableWebSocket
+class JettyWebSocketConfiguration : WebSocketConfigurer {
+
+ override fun registerWebSocketHandlers(registry: WebSocketHandlerRegistry) {
+ registry.addHandler(echoWebSocketHandler(), "/echo").setHandshakeHandler(handshakeHandler())
+ }
+
+ @Bean
+ fun echoWebSocketHandler(): WebSocketHandler {
+ return MyEchoHandler()
+ }
+
+ @Bean
+ fun handshakeHandler(): DefaultHandshakeHandler {
+ val strategy = JettyRequestUpgradeStrategy()
+ strategy.addWebSocketConfigurer {
+ it.inputBufferSize = 8192
+ it.idleTimeout = Duration.ofSeconds(600)
+ }
+ return DefaultHandshakeHandler(strategy)
+ }
+}
+// end::snippet[]
diff --git a/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/websocketserverruntimeconfiguration/WebSocketConfiguration.kt b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/websocketserverruntimeconfiguration/WebSocketConfiguration.kt
new file mode 100644
index 0000000000..32f4357a3e
--- /dev/null
+++ b/framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/websocketserverruntimeconfiguration/WebSocketConfiguration.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.docs.web.websocket.websocketserverruntimeconfiguration
+
+import org.springframework.context.annotation.Bean
+import org.springframework.context.annotation.Configuration
+import org.springframework.web.socket.server.standard.ServletServerContainerFactoryBean
+
+// tag::snippet[]
+@Configuration
+class WebSocketConfiguration {
+
+ @Bean
+ fun createWebSocketContainer() = ServletServerContainerFactoryBean().apply {
+ maxTextMessageBufferSize = 8192
+ maxBinaryMessageBufferSize = 8192
+ }
+}
+// end::snippet[]
diff --git a/framework-docs/src/main/resources/org/springframework/docs/web/websocket/stomp/websocketstompconfigurationperformance/MessageSizeLimitWebSocketConfiguration.xml b/framework-docs/src/main/resources/org/springframework/docs/web/websocket/stomp/websocketstompconfigurationperformance/MessageSizeLimitWebSocketConfiguration.xml
new file mode 100644
index 0000000000..2379035daf
--- /dev/null
+++ b/framework-docs/src/main/resources/org/springframework/docs/web/websocket/stomp/websocketstompconfigurationperformance/MessageSizeLimitWebSocketConfiguration.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/framework-docs/src/main/resources/org/springframework/docs/web/websocket/stomp/websocketstompconfigurationperformance/WebSocketConfiguration.xml b/framework-docs/src/main/resources/org/springframework/docs/web/websocket/stomp/websocketstompconfigurationperformance/WebSocketConfiguration.xml
new file mode 100644
index 0000000000..0926960c9c
--- /dev/null
+++ b/framework-docs/src/main/resources/org/springframework/docs/web/websocket/stomp/websocketstompconfigurationperformance/WebSocketConfiguration.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/framework-docs/src/main/resources/org/springframework/docs/web/websocket/stomp/websocketstompdestinationseparator/WebSocketConfiguration.xml b/framework-docs/src/main/resources/org/springframework/docs/web/websocket/stomp/websocketstompdestinationseparator/WebSocketConfiguration.xml
new file mode 100644
index 0000000000..60f3334ff4
--- /dev/null
+++ b/framework-docs/src/main/resources/org/springframework/docs/web/websocket/stomp/websocketstompdestinationseparator/WebSocketConfiguration.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/framework-docs/src/main/resources/org/springframework/docs/web/websocket/stomp/websocketstompenable/WebSocketConfiguration.xml b/framework-docs/src/main/resources/org/springframework/docs/web/websocket/stomp/websocketstompenable/WebSocketConfiguration.xml
new file mode 100644
index 0000000000..910ef94886
--- /dev/null
+++ b/framework-docs/src/main/resources/org/springframework/docs/web/websocket/stomp/websocketstompenable/WebSocketConfiguration.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/framework-docs/src/main/resources/org/springframework/docs/web/websocket/stomp/websocketstomphandlebrokerrelay/WebSocketConfiguration.xml b/framework-docs/src/main/resources/org/springframework/docs/web/websocket/stomp/websocketstomphandlebrokerrelay/WebSocketConfiguration.xml
new file mode 100644
index 0000000000..0edc2c4499
--- /dev/null
+++ b/framework-docs/src/main/resources/org/springframework/docs/web/websocket/stomp/websocketstomphandlebrokerrelay/WebSocketConfiguration.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/framework-docs/src/main/resources/org/springframework/docs/web/websocket/stomp/websocketstomporderedmessages/PublishOrderWebSocketConfiguration.xml b/framework-docs/src/main/resources/org/springframework/docs/web/websocket/stomp/websocketstomporderedmessages/PublishOrderWebSocketConfiguration.xml
new file mode 100644
index 0000000000..976e6ca573
--- /dev/null
+++ b/framework-docs/src/main/resources/org/springframework/docs/web/websocket/stomp/websocketstomporderedmessages/PublishOrderWebSocketConfiguration.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
diff --git a/framework-docs/src/main/resources/org/springframework/docs/web/websocket/websocketfallbacksockjsenable/WebSocketConfiguration.xml b/framework-docs/src/main/resources/org/springframework/docs/web/websocket/websocketfallbacksockjsenable/WebSocketConfiguration.xml
new file mode 100644
index 0000000000..81ce03b7f4
--- /dev/null
+++ b/framework-docs/src/main/resources/org/springframework/docs/web/websocket/websocketfallbacksockjsenable/WebSocketConfiguration.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/framework-docs/src/main/resources/org/springframework/docs/web/websocket/websocketserverallowedorigins/WebSocketConfiguration.xml b/framework-docs/src/main/resources/org/springframework/docs/web/websocket/websocketserverallowedorigins/WebSocketConfiguration.xml
new file mode 100644
index 0000000000..5736abfcb1
--- /dev/null
+++ b/framework-docs/src/main/resources/org/springframework/docs/web/websocket/websocketserverallowedorigins/WebSocketConfiguration.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/framework-docs/src/main/resources/org/springframework/docs/web/websocket/websocketserverhandler/WebSocketConfiguration.xml b/framework-docs/src/main/resources/org/springframework/docs/web/websocket/websocketserverhandler/WebSocketConfiguration.xml
new file mode 100644
index 0000000000..e400f9eb73
--- /dev/null
+++ b/framework-docs/src/main/resources/org/springframework/docs/web/websocket/websocketserverhandler/WebSocketConfiguration.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/framework-docs/src/main/resources/org/springframework/docs/web/websocket/websocketserverhandshake/WebSocketConfiguration.xml b/framework-docs/src/main/resources/org/springframework/docs/web/websocket/websocketserverhandshake/WebSocketConfiguration.xml
new file mode 100644
index 0000000000..b7bffe51c7
--- /dev/null
+++ b/framework-docs/src/main/resources/org/springframework/docs/web/websocket/websocketserverhandshake/WebSocketConfiguration.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/framework-docs/src/main/resources/org/springframework/docs/web/websocket/websocketserverruntimeconfiguration/WebSocketConfiguration.xml b/framework-docs/src/main/resources/org/springframework/docs/web/websocket/websocketserverruntimeconfiguration/WebSocketConfiguration.xml
new file mode 100644
index 0000000000..c4e067b264
--- /dev/null
+++ b/framework-docs/src/main/resources/org/springframework/docs/web/websocket/websocketserverruntimeconfiguration/WebSocketConfiguration.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+