spring与websocket整合

  • Post author:
  • Post category:其他


首先spring必须用4.0以上,



依赖包:

 1     <dependency>  
 2             <groupId>com.fasterxml.jackson.core</groupId>  
 3             <artifactId>jackson-annotations</artifactId>  
 4             <version>2.3.0</version>  
 5         </dependency>  
 6         <dependency>  
 7             <groupId>com.fasterxml.jackson.core</groupId>  
 8             <artifactId>jackson-core</artifactId>  
 9             <version>2.3.1</version>  
10         </dependency>  
11         <dependency>  
12             <groupId>com.fasterxml.jackson.core</groupId>  
13             <artifactId>jackson-databind</artifactId>  
14             <version>2.3.3</version>  
15         </dependency>  
16         <dependency>    
17            <groupId>org.springframework</groupId>    
18            <artifactId>spring-websocket</artifactId>    
19            <version>4.0.5.RELEASE</version>    
20         </dependency>    
21         <dependency>    
22            <groupId>org.springframework</groupId>    
23            <artifactId>spring-messaging</artifactId>    
24            <version>4.0.5.RELEASE</version>    
25         </dependency> 

编写WebSocketConfig、HandshakeInterceptor与WebSocketHander

 1 import org.springframework.context.annotation.Configuration;  
 2 import org.springframework.web.servlet.config.annotation.EnableWebMvc;  
 3 import org.springframework.web.socket.config.annotation.EnableWebSocket;  
 4 import org.springframework.web.socket.config.annotation.WebSocketConfigurer;  
 5 import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;  
 6   
 7 @Configuration  
 8 @EnableWebMvc  
 9 @EnableWebSocket  
10 public class WebSocketConfig implements WebSocketConfigurer {  
11     @Override  
12     public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {  
13           
14         /** 
15          * 支持websocket 的 connection 
16          */  
17         registry.addHandler(new WebSocketHander(),"/websocket").addInterceptors(new HandshakeInterceptor());  
18           
19         /** 
20          * 不支持websocket的connenction,采用sockjs 
21          */  
22         registry.addHandler(new WebSocketHander(),"/sockjs/websocket").addInterceptors(new HandshakeInterceptor()).withSockJS();  
23     }  
24 }  

 1 import java.util.Map;  
 2   
 3 import org.springframework.http.server.ServerHttpRequest;  
 4 import org.springframework.http.server.ServerHttpResponse;  
 5 import org.springframework.web.socket.WebSocketHandler;  
 6 public class HandshakeInterceptor implements org.springframework.web.socket.server.HandshakeInterceptor {  
 7   
 8     /** 
 9      * Interceptor before hander  
10      */  
11     @Override  
12     public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Map<String, Object> map) throws Exception {  
13         return true;  
14     }  
15   
16     @Override  
17     public void afterHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Exception e) {  
18   
19     }  
20 }  

 1 import java.io.IOException;  
 2 import java.util.ArrayList;  
 3   
 4 import javax.annotation.Resource;  
 5   
 6 import org.slf4j.Logger;  
 7 import org.springframework.web.socket.CloseStatus;  
 8 import org.springframework.web.socket.TextMessage;  
 9 import org.springframework.web.socket.WebSocketHandler;  
10 import org.springframework.web.socket.WebSocketMessage;  
11 import org.springframework.web.socket.WebSocketSession;  
12   
13 public class WebSocketHander implements WebSocketHandler {  
14     
15    private static final Logger logger = org.slf4j.LoggerFactory.getLogger(WebSocketHander.class);  
16       
17     private static final ArrayList<WebSocketSession> users = new ArrayList<WebSocketSession>();  
18   
19     /** 
20      * after connection establish 
21      */  
22     public void afterConnectionEstablished(WebSocketSession session) throws Exception {  
23         logger.info("connect success...");  
24         users.add(session);  
25     }  
26   
27     /** 
28      * process the received message  
29      */  
30     @Override  
31     public void handleMessage(WebSocketSession webSocketSession, WebSocketMessage<?> webSocketMessage) throws Exception {  
32         sendMessageToUsers(new TextMessage(webSocketMessage.getPayload() + "hello"));  
33     }  
34   
35     @Override  
36     public void handleTransportError(WebSocketSession webSocketSession, Throwable throwable) throws Exception {  
37         if(webSocketSession.isOpen()){  
38             webSocketSession.close();  
39         }  
40         logger.info("connenction error,close the connection...");  
41         users.remove(webSocketSession);  
42     }  
43   
44     @Override  
45     public void afterConnectionClosed(WebSocketSession webSocketSession, CloseStatus closeStatus) throws Exception {  
46         logger.info("close the connenction..."+closeStatus.toString());  
47         users.remove(webSocketSession);  
48     }  
49   
50     @Override  
51     public boolean supportsPartialMessages() {  
52         return false;  
53     }  
54     /** 
55      * 给所有在线用户发送消息 
56      * 
57      * @param message 
58      */  
59     public void sendMessageToUsers(TextMessage message) {  
60         for (WebSocketSession user : users) {  
61             try {  
62                 if (user.isOpen()) {  
63                     user.sendMessage(message);  
64                 }  
65             } catch (IOException e) {  
66                 e.printStackTrace();  
67             }  
68         }  
69     }
70 }  

前端页面js

 1 <script type="text/javascript">  
 2         $(function(){  
 3             var websocket;  
 4             if ('WebSocket' in window) {  
 5                 alert("WebSocket");  
 6                 websocket = new WebSocket("ws://localhost:8080/项目名称/websocket");  
 7             } else if ('MozWebSocket' in window) {  
 8                 alert("MozWebSocket");  
 9                 websocket = new MozWebSocket("ws://echo");  
10             } else {  
11                 alert("SockJS");  
12                 websocket = new SockJS("http://localhost:8080/<span style="font-family: Arial, Helvetica, sans-serif;">项目名称</span><span style="font-family: Arial, Helvetica, sans-serif;">/sockjs/websocket");</span>  
13             }  
14             websocket.onopen = function (evnt) {  
15                 $("#tou").html("链接服务器成功!")  
16             };  
17             websocket.onmessage = function (evnt) {  
18                 $("#msg").html($("#msg").html() + "<br/>" + evnt.data);  
19             };  
20             websocket.onerror = function (evnt) {  
21             };  
22             websocket.onclose = function (evnt) {  
23                 $("#tou").html("与服务器断开了链接!")  
24             }  
25             $('#send').bind('click', function() {  
26                 send();  
27             });  
28             function send(){  
29                 if (websocket != null) {  
30                     var message = document.getElementById('message').value;  
31                     websocket.send(message);  
32                 } else {  
33                     alert('未与服务器链接.');  
34                 }  
35             }  
36         });  
37     </script> 


可能出现的错误:


Async support must be enabled on a servlet and for all filters involved in async request processing
如果直接运行,基本上会包上面的错误,我们还需要在web.xml中做如下的配置
<web-app version="3.0"   
xmlns="http://java.sun.com/xml/ns/javaee"   
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee   
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">  

但是2.5的webapp也可以

然后在这个servlet中加入:
1 <async-supported>true</async-supported>  

如:

 1 <servlet>  
 2     <servlet-name>presto-engine</servlet-name>  
 3     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
 4     <init-param>  
 5         <param-name>contextConfigLocation</param-name>  
 6         <param-value>classpath:presto_servlet.xml</param-value>  
 7     </init-param>  
 8     <load-on-startup>1</load-on-startup>  
 9     <async-supported>true</async-supported>  
10 </servlet> 


The extension [x-webkit-deflate-frame] is not supported
在HandshakeInterceptor的beforeHandshake方法中加入
1 public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Map<String, Object> map) throws Exception {  
2     /** 
3      * This is a bug,bug fix:The extension [x-webkit-deflate-frame] is not supported 
4      */  
5     if(request.getHeaders().containsKey("Sec-WebSocket-Extensions")) {  
6         request.getHeaders().set("Sec-WebSocket-Extensions", "permessage-deflate");  
7       }  
8       return true;  
9   }


转自:http://blog.csdn.net/ouyang111222/article/details/50545411

转载于:https://www.cnblogs.com/asen0713/p/6741296.html