From 246f291f67d50c38ed87650f248686adb16374a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Deleuze?= Date: Tue, 9 Apr 2024 12:21:36 +0200 Subject: [PATCH] Use code includes and tabs in WebSocket documentation See gh-22171 --- framework-docs/framework-docs.gradle | 2 + .../ROOT/pages/web/websocket/fallback.adoc | 44 +--- .../ROOT/pages/web/websocket/server.adoc | 214 +----------------- .../stomp/authentication-token-based.adoc | 24 +- .../stomp/configuration-performance.adoc | 74 +----- .../stomp/destination-separator.adoc | 57 +---- .../pages/web/websocket/stomp/enable.adoc | 51 +---- .../stomp/handle-broker-relay-configure.adoc | 22 +- .../websocket/stomp/handle-broker-relay.adoc | 43 +--- .../websocket/stomp/handle-simple-broker.adoc | 27 +-- .../web/websocket/stomp/interceptors.adoc | 27 +-- .../web/websocket/stomp/message-flow.adoc | 28 +-- .../web/websocket/stomp/ordered-messages.adoc | 48 +--- .../web/websocket/stomp/server-config.adoc | 38 +--- .../WebSocketConfiguration.java | 49 ++++ ...essageSizeLimitWebSocketConfiguration.java | 39 ++++ .../WebSocketConfiguration.java | 39 ++++ .../RedController.java | 33 +++ .../WebSocketConfiguration.java | 39 ++++ .../WebSocketConfiguration.java | 47 ++++ .../WebSocketConfiguration.java | 42 ++++ .../WebSocketConfiguration.java | 48 ++++ .../WebSocketConfiguration.java | 49 ++++ .../MyChannelInterceptor.java | 36 +++ .../WebSocketConfiguration.java | 34 +++ .../GreetingController.java | 44 ++++ .../WebSocketConfiguration.java | 41 ++++ .../PublishOrderWebSocketConfiguration.java | 36 +++ .../ReceiveOrderWebSocketConfiguration.java | 35 +++ .../JettyWebSocketConfiguration.java | 49 ++++ .../WebSocketConfiguration.java | 35 +++ .../WebSocketConfiguration.java | 43 ++++ .../WebSocketConfiguration.java | 42 ++++ .../websocketserverhandler/MyHandler.java | 31 +++ .../WebSocketConfiguration.java | 41 ++++ .../WebSocketConfiguration.java | 38 ++++ .../JettyWebSocketConfiguration.java | 55 +++++ .../MyEchoHandler.java | 22 ++ .../WebSocketConfiguration.java | 35 +++ .../WebSocketConfiguration.kt | 48 ++++ .../MessageSizeLimitWebSocketConfiguration.kt | 35 +++ .../WebSocketConfiguration.kt | 35 +++ .../RedController.kt | 33 +++ .../WebSocketConfiguration.kt | 38 ++++ .../WebSocketConfiguration.kt | 45 ++++ .../WebSocketConfiguration.kt | 38 ++++ .../WebSocketConfiguration.kt | 43 ++++ .../WebSocketConfiguration.kt | 47 ++++ .../MyChannelInterceptor.kt | 34 +++ .../WebSocketConfiguration.kt | 33 +++ .../GreetingController.kt | 21 ++ .../WebSocketConfiguration.kt | 39 ++++ .../PublishOrderWebSocketConfiguration.kt | 34 +++ .../ReceiveOrderWebSocketConfiguration.kt | 33 +++ .../JettyWebSocketConfiguration.kt | 48 ++++ .../WebSocketConfiguration.kt | 34 +++ .../WebSocketConfiguration.kt | 39 ++++ .../WebSocketConfiguration.kt | 40 ++++ .../websocketserverhandler/MyHandler.kt | 30 +++ .../WebSocketConfiguration.kt | 40 ++++ .../WebSocketConfiguration.kt | 36 +++ .../JettyWebSocketConfiguration.kt | 52 +++++ .../WebSocketConfiguration.kt | 33 +++ ...MessageSizeLimitWebSocketConfiguration.xml | 17 ++ .../WebSocketConfiguration.xml | 17 ++ .../WebSocketConfiguration.xml | 21 ++ .../WebSocketConfiguration.xml | 17 ++ .../WebSocketConfiguration.xml | 18 ++ .../PublishOrderWebSocketConfiguration.xml | 16 ++ .../WebSocketConfiguration.xml | 19 ++ .../WebSocketConfiguration.xml | 18 ++ .../WebSocketConfiguration.xml | 18 ++ .../WebSocketConfiguration.xml | 21 ++ .../WebSocketConfiguration.xml | 14 ++ 74 files changed, 2138 insertions(+), 667 deletions(-) create mode 100644 framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompauthenticationtokenbased/WebSocketConfiguration.java create mode 100644 framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompconfigurationperformance/MessageSizeLimitWebSocketConfiguration.java create mode 100644 framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompconfigurationperformance/WebSocketConfiguration.java create mode 100644 framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompdestinationseparator/RedController.java create mode 100644 framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompdestinationseparator/WebSocketConfiguration.java create mode 100644 framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompenable/WebSocketConfiguration.java create mode 100644 framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstomphandlebrokerrelay/WebSocketConfiguration.java create mode 100644 framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstomphandlebrokerrelayconfigure/WebSocketConfiguration.java create mode 100644 framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstomphandlesimplebroker/WebSocketConfiguration.java create mode 100644 framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompinterceptors/MyChannelInterceptor.java create mode 100644 framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompinterceptors/WebSocketConfiguration.java create mode 100644 framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompmessageflow/GreetingController.java create mode 100644 framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompmessageflow/WebSocketConfiguration.java create mode 100644 framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstomporderedmessages/PublishOrderWebSocketConfiguration.java create mode 100644 framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstomporderedmessages/ReceiveOrderWebSocketConfiguration.java create mode 100644 framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompserverconfig/JettyWebSocketConfiguration.java create mode 100644 framework-docs/src/main/java/org/springframework/docs/web/websocket/stomp/websocketstompserverconfig/WebSocketConfiguration.java create mode 100644 framework-docs/src/main/java/org/springframework/docs/web/websocket/websocketfallbacksockjsenable/WebSocketConfiguration.java create mode 100644 framework-docs/src/main/java/org/springframework/docs/web/websocket/websocketserverallowedorigins/WebSocketConfiguration.java create mode 100644 framework-docs/src/main/java/org/springframework/docs/web/websocket/websocketserverhandler/MyHandler.java create mode 100644 framework-docs/src/main/java/org/springframework/docs/web/websocket/websocketserverhandler/WebSocketConfiguration.java create mode 100644 framework-docs/src/main/java/org/springframework/docs/web/websocket/websocketserverhandshake/WebSocketConfiguration.java create mode 100644 framework-docs/src/main/java/org/springframework/docs/web/websocket/websocketserverruntimeconfiguration/JettyWebSocketConfiguration.java create mode 100644 framework-docs/src/main/java/org/springframework/docs/web/websocket/websocketserverruntimeconfiguration/MyEchoHandler.java create mode 100644 framework-docs/src/main/java/org/springframework/docs/web/websocket/websocketserverruntimeconfiguration/WebSocketConfiguration.java create mode 100644 framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompauthenticationtokenbased/WebSocketConfiguration.kt create mode 100644 framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompconfigurationperformance/MessageSizeLimitWebSocketConfiguration.kt create mode 100644 framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompconfigurationperformance/WebSocketConfiguration.kt create mode 100644 framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompdestinationseparator/RedController.kt create mode 100644 framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompdestinationseparator/WebSocketConfiguration.kt create mode 100644 framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompenable/WebSocketConfiguration.kt create mode 100644 framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstomphandlebrokerrelay/WebSocketConfiguration.kt create mode 100644 framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstomphandlebrokerrelayconfigure/WebSocketConfiguration.kt create mode 100644 framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstomphandlesimplebroker/WebSocketConfiguration.kt create mode 100644 framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompinterceptors/MyChannelInterceptor.kt create mode 100644 framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompinterceptors/WebSocketConfiguration.kt create mode 100644 framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompmessageflow/GreetingController.kt create mode 100644 framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompmessageflow/WebSocketConfiguration.kt create mode 100644 framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstomporderedmessages/PublishOrderWebSocketConfiguration.kt create mode 100644 framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstomporderedmessages/ReceiveOrderWebSocketConfiguration.kt create mode 100644 framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompserverconfig/JettyWebSocketConfiguration.kt create mode 100644 framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/stomp/websocketstompserverconfig/WebSocketConfiguration.kt create mode 100644 framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/websocketfallbacksockjsenable/WebSocketConfiguration.kt create mode 100644 framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/websocketserverallowedorigins/WebSocketConfiguration.kt create mode 100644 framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/websocketserverhandler/MyHandler.kt create mode 100644 framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/websocketserverhandler/WebSocketConfiguration.kt create mode 100644 framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/websocketserverhandshake/WebSocketConfiguration.kt create mode 100644 framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/websocketserverruntimeconfiguration/JettyWebSocketConfiguration.kt create mode 100644 framework-docs/src/main/kotlin/org/springframework/docs/web/websocket/websocketserverruntimeconfiguration/WebSocketConfiguration.kt create mode 100644 framework-docs/src/main/resources/org/springframework/docs/web/websocket/stomp/websocketstompconfigurationperformance/MessageSizeLimitWebSocketConfiguration.xml create mode 100644 framework-docs/src/main/resources/org/springframework/docs/web/websocket/stomp/websocketstompconfigurationperformance/WebSocketConfiguration.xml create mode 100644 framework-docs/src/main/resources/org/springframework/docs/web/websocket/stomp/websocketstompdestinationseparator/WebSocketConfiguration.xml create mode 100644 framework-docs/src/main/resources/org/springframework/docs/web/websocket/stomp/websocketstompenable/WebSocketConfiguration.xml create mode 100644 framework-docs/src/main/resources/org/springframework/docs/web/websocket/stomp/websocketstomphandlebrokerrelay/WebSocketConfiguration.xml create mode 100644 framework-docs/src/main/resources/org/springframework/docs/web/websocket/stomp/websocketstomporderedmessages/PublishOrderWebSocketConfiguration.xml create mode 100644 framework-docs/src/main/resources/org/springframework/docs/web/websocket/websocketfallbacksockjsenable/WebSocketConfiguration.xml create mode 100644 framework-docs/src/main/resources/org/springframework/docs/web/websocket/websocketserverallowedorigins/WebSocketConfiguration.xml create mode 100644 framework-docs/src/main/resources/org/springframework/docs/web/websocket/websocketserverhandler/WebSocketConfiguration.xml create mode 100644 framework-docs/src/main/resources/org/springframework/docs/web/websocket/websocketserverhandshake/WebSocketConfiguration.xml create mode 100644 framework-docs/src/main/resources/org/springframework/docs/web/websocket/websocketserverruntimeconfiguration/WebSocketConfiguration.xml 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 @@ + + + + + + + + + + +