JAVA-14459, GitHub Issue: Reactive WebSocket App example no longer works. (#13272)

Co-authored-by: jogra <joseph.sterling.grah@miles.no>
This commit is contained in:
jsgrah-spring 2023-01-12 18:55:18 +01:00 committed by GitHub
parent dcc489edfa
commit 10644de954
6 changed files with 98 additions and 8 deletions

View File

@ -26,7 +26,11 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId> <artifactId>spring-boot-starter-integration</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>javax.json.bind</groupId> <groupId>javax.json.bind</groupId>
@ -111,6 +115,10 @@
<groupId>org.apache.httpcomponents</groupId> <groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId> <artifactId>httpclient</artifactId>
</dependency> </dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
</dependency>
</dependencies> </dependencies>
<build> <build>

View File

@ -2,8 +2,9 @@ package com.baeldung.reactive;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
@SpringBootApplication @SpringBootApplication(exclude = { RedisAutoConfiguration.class })
public class Spring5ReactiveApplication{ public class Spring5ReactiveApplication{
public static void main(String[] args) { public static void main(String[] args) {

View File

@ -2,8 +2,22 @@ package com.baeldung.websocket;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
import org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration;
import org.springframework.boot.autoconfigure.security.oauth2.client.reactive.ReactiveOAuth2ClientAutoConfiguration;
import org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration;
import org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration;
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
@SpringBootApplication @SpringBootApplication(exclude = {
SecurityAutoConfiguration.class,
UserDetailsServiceAutoConfiguration.class,
ReactiveSecurityAutoConfiguration.class,
ReactiveUserDetailsServiceAutoConfiguration.class,
ReactiveOAuth2ClientAutoConfiguration.class,
WebMvcAutoConfiguration.class,
RedisAutoConfiguration.class})
public class ReactiveWebSocketApplication { public class ReactiveWebSocketApplication {
public static void main(String[] args) { public static void main(String[] args) {
SpringApplication.run(ReactiveWebSocketApplication.class, args); SpringApplication.run(ReactiveWebSocketApplication.class, args);

View File

@ -10,19 +10,25 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.HandlerMapping; import org.springframework.web.reactive.HandlerMapping;
import org.springframework.web.reactive.handler.SimpleUrlHandlerMapping; import org.springframework.web.reactive.handler.SimpleUrlHandlerMapping;
import org.springframework.web.reactive.socket.WebSocketHandler; import org.springframework.web.reactive.socket.WebSocketHandler;
import org.springframework.web.reactive.socket.server.WebSocketService;
import org.springframework.web.reactive.socket.server.support.HandshakeWebSocketService;
import org.springframework.web.reactive.socket.server.upgrade.TomcatRequestUpgradeStrategy;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.reactive.socket.server.support.WebSocketHandlerAdapter; import org.springframework.web.reactive.socket.server.support.WebSocketHandlerAdapter;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
@Configuration @Configuration
@EnableWebSocket
public class ReactiveWebSocketConfiguration { public class ReactiveWebSocketConfiguration {
@Autowired @Autowired
@Qualifier("ReactiveWebSocketHandler") @Qualifier("ReactiveWebSocketHandler")
private WebSocketHandler webSocketHandler; private ReactiveWebSocketHandler reactiveWebSocketHandler;
@Bean @Bean
public HandlerMapping webSocketHandlerMapping() { public HandlerMapping reactiveWebSocketHandlerMapping() {
Map<String, WebSocketHandler> map = new HashMap<>(); Map<String, WebSocketHandler> map = new HashMap<>();
map.put("/event-emitter", webSocketHandler); map.put("/event-emitter", reactiveWebSocketHandler);
SimpleUrlHandlerMapping handlerMapping = new SimpleUrlHandlerMapping(); SimpleUrlHandlerMapping handlerMapping = new SimpleUrlHandlerMapping();
handlerMapping.setOrder(1); handlerMapping.setOrder(1);
@ -32,6 +38,26 @@ public class ReactiveWebSocketConfiguration {
@Bean @Bean
public WebSocketHandlerAdapter handlerAdapter() { public WebSocketHandlerAdapter handlerAdapter() {
return new WebSocketHandlerAdapter(); return new WebSocketHandlerAdapter(webSocketService());
}
@Bean
public WebSocketService webSocketService() {
TomcatRequestUpgradeStrategy tomcatRequestUpgradeStrategy = new TomcatRequestUpgradeStrategy();
tomcatRequestUpgradeStrategy.setMaxSessionIdleTimeout(10000L);
tomcatRequestUpgradeStrategy.setAsyncSendTimeout(10000L);
return new HandshakeWebSocketService(tomcatRequestUpgradeStrategy);
}
@Bean
public ServerEndpointExporter serverEndpointExporter() {
ServerEndpointExporter serverEndpointExporter = new ServerEndpointExporter();
/**
* Add one or more classes annotated with `@ServerEndpoint`.
*/
serverEndpointExporter.setAnnotatedEndpointClasses(WebSocketController.class);
return serverEndpointExporter;
} }
} }

View File

@ -0,0 +1,40 @@
package com.baeldung.websocket;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@ServerEndpoint("/event-emitter")
public class WebSocketController {
private static final Logger LOGGER = LoggerFactory.getLogger(WebSocketController.class);
@OnOpen
public void onOpen(Session session, EndpointConfig endpointConfig) throws IOException {
// Get session and WebSocket connection
session.setMaxIdleTimeout(0);
LOGGER.info("Get session and WebSocket connection");
}
@OnMessage
public void onMessage(String message, Session session) throws IOException {
// Handle new messages
LOGGER.info("Handle new messages -> {}", message );
}
@OnClose
public void onClose(Session session) throws IOException {
// WebSocket connection closes
LOGGER.info("WebSocket connection closes");
}
@OnError
public void onError(Session session, Throwable throwable) {
// Do error handling here
LOGGER.info("Do error handling here");
}
}

View File

@ -1 +1,2 @@
logging.level.root=INFO logging.level.root=INFO
server.tomcat.max-keep-alive-requests=1