折騰了將近一天,終于搭建好websocket服務(wù),中間遇到不少的坑,現(xiàn)在記錄一下,也供他們參考少走彎路。
開發(fā)環(huán)境:<spring.version>4.2.5.RELEASE</spring.version> Tomcat8 jdk8 maven
spring搭建websocket有兩種方式:
1、利用javaee-api以注解的形式搭建,見(jiàn)上一篇博文《spring+tomcat8實(shí)現(xiàn)websocket
》
2、利用spring-websocket包搭建,本篇介紹的內(nèi)容。
注意:這種方式必須注釋掉這個(gè),不然會(huì)沖突
<!-- <dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
</dependency> -->
需要用到的spring包:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-messaging</artifactId>
<version>${spring.version}</version>
</dependency>
其他輔助包:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson-version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson-version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson-version}</version>
</dependency>
Java代碼:兩個(gè)類 WebSocketConfig 和 SystemWebSocketHandler
- @Configuration
- @EnableWebMvc
- @EnableWebSocket
- public class WebSocketConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer{
-
- @Override
- public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
- registry.addHandler(systemWebSocketHandler(),"/webSocketServer");
- registry.addHandler(systemWebSocketHandler(),"/webSocketServer/sockjs").setAllowedOrigins("*").withSockJS();
- //registry.addHandler(systemWebSocketHandler(),"/webSocketServer").addInterceptors(new WebSocketHandshakeInterceptor());
- //registry.addHandler(systemWebSocketHandler(), "/sockjs/webSocketServer").addInterceptors(new WebSocketHandshakeInterceptor()).withSockJS();
- //registry.addHandler(systemWebSocketHandler(), "/webSocketServer/sockjs").withSockJS();
- /*registry.addHandler(systemWebSocketHandler(),"/ws").addInterceptors(new WebSocketHandshakeInterceptor());
- registry.addHandler(systemWebSocketHandler(), "/ws/sockjs").addInterceptors(new WebSocketHandshakeInterceptor())
- .withSockJS();*/
- }
-
- @Bean
- public WebSocketHandler systemWebSocketHandler(){
- return new SystemWebSocketHandler();
- }
-
- import java.io.IOException;
- import java.util.ArrayList;
- import java.util.Date;
-
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.messaging.Message;
- import org.springframework.web.socket.CloseStatus;
- import org.springframework.web.socket.TextMessage;
- import org.springframework.web.socket.WebSocketHandler;
- import org.springframework.web.socket.WebSocketMessage;
- import org.springframework.web.socket.WebSocketSession;
-
- import com.mspj.frame.core.web.controller.BaseWebControllerImpl;
-
- public class SystemWebSocketHandler implements WebSocketHandler {
-
- private Logger log = LoggerFactory.getLogger(SystemWebSocketHandler.class);
-
- private static final ArrayList<WebSocketSession> users = new ArrayList<WebSocketSession>();;
-
-
- @Override
- public void afterConnectionEstablished(WebSocketSession session) throws Exception {
- System.out.println("ConnectionEstablished");
- log.debug("ConnectionEstablished");
- users.add(session);
-
- session.sendMessage(new TextMessage("connect"));
- session.sendMessage(new TextMessage("new_msg"));
-
- }
-
- @Override
- public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
- System.out.println("handleMessage" + message.toString());
- log.debug("handleMessage" + message.toString());
- //sendMessageToUsers();
- session.sendMessage(new TextMessage(new Date() + ""));
- }
-
- @Override
- public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
- if(session.isOpen()){
- session.close();
- }
- users.remove(session);
-
- log.debug("handleTransportError" + exception.getMessage());
- }
-
- @Override
- public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
- users.remove(session);
- log.debug("afterConnectionClosed" + closeStatus.getReason());
-
- }
-
- @Override
- public boolean supportsPartialMessages() {
- return false;
- }
-
- /**
- * 給所有在線用戶發(fā)送消息
- *
- * @param message
- */
- public void sendMessageToUsers(TextMessage message) {
- for (WebSocketSession user : users) {
- try {
- if (user.isOpen()) {
- user.sendMessage(message);
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
-
- }
前端調(diào)式頁(yè)面代碼
最后說(shuō)下幾個(gè)坑點(diǎn):
1、html頁(yè)面訪問(wèn)限制的問(wèn)題的:403 Forbidden
- registry.addHandler(systemWebSocketHandler(),"/webSocketServer/sockjs").setAllowedOrigins("*").withSockJS();
2、web.xml配置需要升級(jí)成3.1
xsi:schemaLocation="http://java./xml/ns/javaee http://java./xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
3、web.xml里面所有過(guò)濾器需要加上
<async-supported>true</async-supported>
如:
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
|