Add WebSocketAutoConfiguration
Opinionated defaults for WebSockets: * If spring-websocket is on the classpath and so is the Tomcat WSci initializer then it is added to the context * A DefaultSockJsService is added if none is present * User has only to define @Beans of type WebSocketHandler with name starting "/" * Each one is converted to a SockJsHttpRequestHandler and mapped to "/<beanName>/**"
This commit is contained in:
@@ -16,16 +16,8 @@
|
||||
|
||||
package org.springframework.boot.samples.websocket.config;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.catalina.Context;
|
||||
import org.apache.catalina.startup.Tomcat;
|
||||
import org.apache.tomcat.websocket.server.WsSci;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
|
||||
import org.springframework.boot.samples.websocket.client.GreetingService;
|
||||
import org.springframework.boot.samples.websocket.client.SimpleGreetingService;
|
||||
import org.springframework.boot.samples.websocket.echo.DefaultEchoService;
|
||||
@@ -35,19 +27,13 @@ import org.springframework.boot.samples.websocket.snake.SnakeWebSocketHandler;
|
||||
import org.springframework.boot.web.SpringBootServletInitializer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
|
||||
import org.springframework.web.servlet.DispatcherServlet;
|
||||
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
|
||||
import org.springframework.web.socket.WebSocketHandler;
|
||||
import org.springframework.web.socket.server.support.WebSocketHttpRequestHandler;
|
||||
import org.springframework.web.socket.sockjs.SockJsHttpRequestHandler;
|
||||
import org.springframework.web.socket.sockjs.SockJsService;
|
||||
import org.springframework.web.socket.sockjs.transport.handler.DefaultSockJsService;
|
||||
import org.springframework.web.socket.support.PerConnectionWebSocketHandler;
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
public class SampleWebSocketsApplication extends SpringBootServletInitializer {
|
||||
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getConfigClasses() {
|
||||
return new Class<?>[] { SampleWebSocketsApplication.class };
|
||||
@@ -57,22 +43,6 @@ public class SampleWebSocketsApplication extends SpringBootServletInitializer {
|
||||
SpringApplication.run(SampleWebSocketsApplication.class, args);
|
||||
}
|
||||
|
||||
@ConditionalOnClass(Tomcat.class)
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
protected static class InitializationConfiguration {
|
||||
@Bean
|
||||
public TomcatEmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory() {
|
||||
TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory() {
|
||||
@Override
|
||||
protected void postProcessContext(Context context) {
|
||||
context.addServletContainerInitializer(new WsSci(), null);
|
||||
}
|
||||
};
|
||||
return factory;
|
||||
}
|
||||
}
|
||||
|
||||
@Bean
|
||||
public EchoService echoService() {
|
||||
return new DefaultEchoService("Did you say \"%s\"?");
|
||||
@@ -83,47 +53,14 @@ public class SampleWebSocketsApplication extends SpringBootServletInitializer {
|
||||
return new SimpleGreetingService();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SimpleUrlHandlerMapping handlerMapping() {
|
||||
|
||||
SockJsService sockJsService = new DefaultSockJsService(sockJsTaskScheduler());
|
||||
|
||||
Map<String, Object> urlMap = new HashMap<String, Object>();
|
||||
|
||||
urlMap.put("/echo", new WebSocketHttpRequestHandler(echoWebSocketHandler()));
|
||||
urlMap.put("/snake", new WebSocketHttpRequestHandler(snakeWebSocketHandler()));
|
||||
|
||||
urlMap.put("/sockjs/echo/**", new SockJsHttpRequestHandler(sockJsService, echoWebSocketHandler()));
|
||||
urlMap.put("/sockjs/snake/**", new SockJsHttpRequestHandler(sockJsService, snakeWebSocketHandler()));
|
||||
|
||||
SimpleUrlHandlerMapping handlerMapping = new SimpleUrlHandlerMapping();
|
||||
handlerMapping.setOrder(-1);
|
||||
handlerMapping.setUrlMap(urlMap);
|
||||
|
||||
return handlerMapping;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DispatcherServlet dispatcherServlet() {
|
||||
DispatcherServlet servlet = new DispatcherServlet();
|
||||
servlet.setDispatchOptionsRequest(true);
|
||||
return servlet;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Bean(name = "/echo")
|
||||
public WebSocketHandler echoWebSocketHandler() {
|
||||
return new PerConnectionWebSocketHandler(EchoWebSocketHandler.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Bean(name = "/snake")
|
||||
public WebSocketHandler snakeWebSocketHandler() {
|
||||
return new SnakeWebSocketHandler();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ThreadPoolTaskScheduler sockJsTaskScheduler() {
|
||||
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
|
||||
taskScheduler.setThreadNamePrefix("SockJS-");
|
||||
return taskScheduler;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
<script src="http://cdn.sockjs.org/sockjs-0.3.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
var ws = null;
|
||||
|
||||
@@ -60,15 +61,7 @@
|
||||
|
||||
function connect() {
|
||||
var target = document.getElementById('target').value;
|
||||
target = "ws://" + window.location.host + target
|
||||
if ('WebSocket' in window) {
|
||||
ws = new WebSocket(target);
|
||||
} else if ('MozWebSocket' in window) {
|
||||
ws = new MozWebSocket(target);
|
||||
} else {
|
||||
alert('WebSocket is not supported by this browser.');
|
||||
return;
|
||||
}
|
||||
ws = new SockJS(target);
|
||||
ws.onopen = function () {
|
||||
setConnected(true);
|
||||
log('Info: WebSocket connection opened.');
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
<script src="http://cdn.sockjs.org/sockjs-0.3.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<noscript><h2 style="color: #ff0000">Seems your browser doesn't support Javascript! Websockets rely on Javascript being enabled. Please enable
|
||||
@@ -110,11 +111,7 @@
|
||||
}
|
||||
}
|
||||
}, false);
|
||||
if (window.location.protocol == 'http:') {
|
||||
Game.connect('ws://' + window.location.host + '/snake');
|
||||
} else {
|
||||
Game.connect('wss://' + window.location.host + '/snake');
|
||||
}
|
||||
Game.connect();
|
||||
};
|
||||
|
||||
Game.setDirection = function(direction) {
|
||||
@@ -185,15 +182,8 @@
|
||||
};
|
||||
})();
|
||||
|
||||
Game.connect = (function(host) {
|
||||
if ('WebSocket' in window) {
|
||||
Game.socket = new WebSocket(host);
|
||||
} else if ('MozWebSocket' in window) {
|
||||
Game.socket = new MozWebSocket(host);
|
||||
} else {
|
||||
Console.log('Error: WebSocket is not supported by this browser.');
|
||||
return;
|
||||
}
|
||||
Game.connect = (function() {
|
||||
Game.socket = new SockJS("/snake");
|
||||
|
||||
Game.socket.onopen = function () {
|
||||
// Socket open.. start the game loop.
|
||||
|
||||
@@ -34,7 +34,6 @@ import org.springframework.boot.samples.websocket.client.GreetingService;
|
||||
import org.springframework.boot.samples.websocket.client.SimpleClientWebSocketHandler;
|
||||
import org.springframework.boot.samples.websocket.client.SimpleGreetingService;
|
||||
import org.springframework.boot.samples.websocket.config.SampleWebSocketsApplication;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -45,7 +44,7 @@ public class SampleWebSocketsApplicationTests {
|
||||
|
||||
private static Log logger = LogFactory.getLog(SampleWebSocketsApplicationTests.class);
|
||||
|
||||
private static final String WS_URI = "ws://localhost:8080/echo";
|
||||
private static final String WS_URI = "ws://localhost:8080/echo/websocket";
|
||||
|
||||
private static ConfigurableApplicationContext context;
|
||||
|
||||
@@ -72,8 +71,10 @@ public class SampleWebSocketsApplicationTests {
|
||||
|
||||
@Test
|
||||
public void runAndWait() throws Exception {
|
||||
ApplicationContext context = SpringApplication.run(ClientConfiguration.class, "--spring.main.web_environment=false");
|
||||
assertEquals(0, context.getBean(ClientConfiguration.class).latch.getCount());
|
||||
ConfigurableApplicationContext context = (ConfigurableApplicationContext) SpringApplication.run(ClientConfiguration.class, "--spring.main.web_environment=false");
|
||||
long count = context.getBean(ClientConfiguration.class).latch.getCount();
|
||||
context.close();
|
||||
assertEquals(0, count);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@@ -84,7 +85,7 @@ public class SampleWebSocketsApplicationTests {
|
||||
@Override
|
||||
public void run(String... args) throws Exception {
|
||||
logger.info("Waiting for response: latch=" + latch.getCount());
|
||||
latch.await();
|
||||
latch.await(10, TimeUnit.SECONDS);
|
||||
logger.info("Got response: latch=" + latch.getCount());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user