websoket在项目中的使用

Posted songstar

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了websoket在项目中的使用相关的知识,希望对你有一定的参考价值。

       项目中要求用户A发起终止申请请求后,对应的相关权限的用户B、用户C等即时收到终止的请求,针对这个需求在项目中加入了websoket功能,下面是具体的使用过程。

1.在maven中添加jar引用

技术图片
1 <dependency>
2 <groupId>org.springframework</groupId>
3 <artifactId>spring-websocket</artifactId>
4  <version>5.0.9.RELEASE</version>
5 </dependency>
View Code

2.在xml的配置,在websocket-context.xml的配置,在service-context.xml的引入

技术图片
<?xml version="1.0" encoding="UTF-8"?>
<beans 
    xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p" 
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:websocket="http://www.springframework.org/schema/websocket"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-4.1.xsd
    http://www.springframework.org/schema/aop 
    http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
    http://www.springframework.org/schema/websocket
    http://www.springframework.org/schema/websocket/spring-websocket-4.1.xsd">
<!--
    <aop:aspectj-autoproxy proxy-target-class="true" />
     Enables the Spring MVC @Controller programming model -->
     
    <bean id="userWebsocket" class="com.gta.scm.websocket.UserWebsocket">
    </bean>
     
    <bean id="websocket" class="com.gta.scm.websocket.WebsocketEndPoint"> 
        <property name="list">  
            <list>  
                <ref bean="userWebsocket" />  
            </list>  
        </property>  
    </bean> 
  
    <websocket:handlers allowed-origins="*">  
        <websocket:mapping path="/websocket.do" handler="websocket"/>  
        <websocket:handshake-interceptors>  
        <bean class="com.gta.scm.websocket.HandshakeInterceptor">  
            <property name="list">  
                <list>  
                    <ref bean="userWebsocket" />  
                </list>  
            </property>  
        </bean> 
        </websocket:handshake-interceptors>  
    </websocket:handlers> 
</beans>
View Code

 <import resource="websocket-context.xml"/>

3.在后台拦截器和处理类

技术图片

 

会话拦截器

技术图片
 1 import java.util.List;
 2 import java.util.Map;
 3 
 4 import org.springframework.http.server.ServerHttpRequest;
 5 import org.springframework.http.server.ServerHttpResponse;
 6 import org.springframework.stereotype.Component;
 7 import org.springframework.web.socket.WebSocketHandler;
 8 import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;
 9 
10 import com.gta.scm.websocket.intercept.ServiceHandshakeInterceptor;
11 
12 
13 @Component
14 public class HandshakeInterceptor extends HttpSessionHandshakeInterceptor
15     public static final String JSESSIONID = "JSESSIONID";
16     private List<ServiceHandshakeInterceptor> list;
17     /**
18      * 当用户连接ServerSocket时执行
19      * 通过request获取用户登陆的jsessionId的值,放入到集合attributes中
20      */
21     @Override  
22     public boolean beforeHandshake(ServerHttpRequest request,  
23             ServerHttpResponse response, WebSocketHandler wsHandler,  
24             Map<String, Object> attributes) throws Exception   
25  
26         if(list!=null)
27             for (ServiceHandshakeInterceptor serviceHandshakeInterceptor : list) 
28                 serviceHandshakeInterceptor.beforeHandshake(request, response, wsHandler, attributes);
29             
30         
31         return super.beforeHandshake(request, response, wsHandler, attributes);  
32       
33     
34  
35   
36     /**
37      * 当用户连接完ServerSocket时执行
38      */
39     @Override  
40     public void afterHandshake(ServerHttpRequest request,  
41             ServerHttpResponse response, WebSocketHandler wsHandler,  
42             Exception ex)   
43         if(list!=null)
44             for (ServiceHandshakeInterceptor serviceHandshakeInterceptor : list) 
45                 serviceHandshakeInterceptor.afterHandshake(request, response, wsHandler, ex); 
46             
47         
48         super.afterHandshake(request, response, wsHandler, ex);  
49     
50 
51 
52 
53     public List<ServiceHandshakeInterceptor> getList() 
54         return list;
55     
56 
57 
58 
59     public void setList(List<ServiceHandshakeInterceptor> list) 
60         this.list = list;
61       
62 
63 
View Code
技术图片
 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 
 7 public interface ServiceHandshakeInterceptor 
 8     public void beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
 9             Map<String, Object> attributes);
10 
11     public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
12             Exception ex);
13 
View Code

websokect处理器

技术图片
 1 import org.springframework.web.socket.CloseStatus;
 2 import org.springframework.web.socket.TextMessage;
 3 import org.springframework.web.socket.WebSocketSession;
 4 
 5 public interface ServiceTextWebSocketHandler 
 6     public void handleTextMessage(WebSocketSession session, TextMessage message) ;
 7     public void afterConnectionEstablished(WebSocketSession session);
 8     public void handleTransportError(WebSocketSession session, Throwable exception) ;
 9     public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) ; 
10         
11 
View Code
技术图片
 1 import java.util.List;
 2 
 3 import org.springframework.stereotype.Component;
 4 import org.springframework.web.socket.CloseStatus;
 5 import org.springframework.web.socket.TextMessage;
 6 import org.springframework.web.socket.WebSocketSession;
 7 import org.springframework.web.socket.handler.TextWebSocketHandler;
 8 
 9 import com.gta.scm.websocket.intercept.ServiceTextWebSocketHandler;
10 @Component
11 public class WebsocketEndPoint extends TextWebSocketHandler 
12     // 所有连接用户的WebSocketSession,键是用户的jsessionID,值是连接的会话对象
13     private List<ServiceTextWebSocketHandler> list;
14     /**
15      * 该方法在用户前端进行发送消息后进行业务处理的行为
16      */
17     @Override
18     public void handleTextMessage(WebSocketSession session, TextMessage message) 
19 
20         if (list!=null) 
21             for (ServiceTextWebSocketHandler serviceTextWebSocketHandler : list) 
22                 serviceTextWebSocketHandler.handleTextMessage(session, message);
23             
24         
25     
26 
27     /**
28      * 该方法是连接生效后进行的处理业务行为,每个用户和服务端建立websocket链接时调用
29      */
30     @Override
31     public void afterConnectionEstablished(WebSocketSession session) throws Exception 
32         // 与客户端完成连接后调用
33         if (list!=null) 
34             for (ServiceTextWebSocketHandler serviceTextWebSocketHandler : list) 
35                 serviceTextWebSocketHandler.afterConnectionEstablished(session);
36             
37         
38     
39 
40     @Override
41     public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception 
42         // 消息传输出错时调用
43         if (list!=null) 
44             for (ServiceTextWebSocketHandler serviceTextWebSocketHandler : list) 
45                 serviceTextWebSocketHandler.handleTransportError(session,exception);
46             
47         
48     
49 
50     @Override
51     public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception 
52         if (list!=null) 
53             for (ServiceTextWebSocketHandler serviceTextWebSocketHandler : list) 
54                 serviceTextWebSocketHandler.afterConnectionClosed(session,closeStatus);
55             
56         
57     
58 
59     @Override
60     public boolean supportsPartialMessages() 
61         return false;
62     
63 
64     public List<ServiceTextWebSocketHandler> getList() 
65         return list;
66     
67 
68     public void setList(List<ServiceTextWebSocketHandler> list) 
69         this.list = list;
70     
71     
72  
73     
74 
75 
View Code
技术图片
  1 import java.io.IOException;
  2 import java.util.HashMap;
  3 import java.util.Iterator;
  4 import java.util.List;
  5 import java.util.Map;
  6 import java.util.Map.Entry;
  7 import java.util.Set;
  8 
  9 import javax.servlet.http.Cookie;
 10 
 11 import org.apache.commons.lang.StringUtils;
 12 import org.slf4j.Logger;
 13 import org.slf4j.LoggerFactory;
 14 import org.springframework.http.server.ServerHttpRequest;
 15 import org.springframework.http.server.ServerHttpResponse;
 16 import org.springframework.http.server.ServletServerHttpRequest;
 17 import org.springframework.stereotype.Component;
 18 import org.springframework.web.socket.CloseStatus;
 19 import org.springframework.web.socket.TextMessage;
 20 import org.springframework.web.socket.WebSocketHandler;
 21 import org.springframework.web.socket.WebSocketSession;
 22 import org.springframework.web.socket.handler.TextWebSocketHandler;
 23 
 24 import com.gta.scm.common.constant.CommonConstant;
 25 import com.gta.scm.common.login.UserLoginRsp;
 26 import com.gta.scm.websocket.intercept.ServiceHandshakeInterceptor;
 27 import com.gta.scm.websocket.intercept.ServiceTextWebSocketHandler;
 28 
 29 @Component
 30 public class UserWebsocket  implements ServiceTextWebSocketHandler,ServiceHandshakeInterceptor
 31     Logger logger = LoggerFactory.getLogger(UserWebsocket.class);
 32     public static final String JSESSIONID = "JSESSIONID";
 33     private static final Map<String,WebSocketSession> users = new HashMap<String,WebSocketSession>();
 34     
 35     /**
 36      * 该方法在用户前端进行发送消息后进行业务处理的行为
 37      */
 38     @Override
 39     public void handleTextMessage(WebSocketSession session, TextMessage message) 
 40         logger.debug("handleTextMessage...");    
 41          try 
 42             sendMsgToUsers(message.getPayload(), session.getId()) ;
 43          catch (Exception e) 
 44             e.printStackTrace();
 45         
 46     
 47 
 48     /**
 49      * 该方法是连接生效后进行的处理业务行为,每个用户和服务端建立websocket链接时调用
 50      */
 51     @Override
 52     public void afterConnectionEstablished(WebSocketSession session) 
 53         logger.debug("afterConnectionEstablished...");    
 54         Map<String, Object> m = session.getAttributes();
 55         UserLoginRsp user = (UserLoginRsp) m.get(CommonConstant.LOGIN_USER);
 56         users.put(user.getUserInfoId().toString(), session);
 57         logger.debug("put "+user.getUserAccount()+" in sessions");    
 58     
 59     
 60     private String getJsessionId(WebSocketSession session)
 61         Object jsessionIdObj = session.getAttributes().get(HandshakeInterceptor.JSESSIONID);
 62         if (jsessionIdObj != null) 
 63             return jsessionIdObj.toString();
 64         
 65         return null;
 66     
 67     
 68     @Override
 69     public void handleTransportError(WebSocketSession session, Throwable exception) 
 70         logger.debug("handleTransportError...");    
 71          if(session.isOpen())
 72             try 
 73                 session.close();
 74              catch (IOException e) 
 75                 logger.debug("handleTransportError...",e);    
 76             
 77         
 78         logger.debug("connection closed......");
 79         Map<String, Object> m = session.getAttributes();
 80         UserLoginRsp user = (UserLoginRsp) m.get(CommonConstant.LOGIN_USER);
 81         if(user!=null && users.get(user.getUserInfoId().toString())!=null) 
 82             users.remove(user.getUserInfoId().toString(), session);
 83         
 84         logger.debug("remove user success......");
 85     
 86     // 一个客户端连接断开时关闭
 87     @Override
 88     public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) 
 89         logger.debug("afterConnectionClosed...");    
 90         Map<String, Object> m = session.getAttributes();
 91         UserLoginRsp user = (UserLoginRsp) m.get(CommonConstant.LOGIN_USER);
 92         if(user!=null && users.get(user.getUserInfoId().toString())!=null) 
 93             users.remove(user.getUserInfoId().toString(), session);
 94         
 95         
 96     
 97     /**向所有用户发送 信息
 98      * @param message
 99      * @throws Exception
100      */
101     public void sendMsgToAllUsers(String message) throws Exception
102         logger.debug("sendMsgToAllUsers...");    
103         Entry<String,WebSocketSession> entry = null;
104         Iterator<Entry<String,WebSocketSession>> entryIt = users.entrySet().iterator();
105         while(entryIt.hasNext()) 
106             entry = entryIt.next();
107             entry.getValue().sendMessage(new TextMessage(message.getBytes()));
108         
109     
110     
111     /**向Set<String> jsessionSet 中设置的用户发送信息
112      * @param message
113      * @param jsessionSet
114      * @throws Exception
115      */
116     public void sendMsgToUsers(String message,Set<String> jsessionSet) throws Exception
117         logger.debug("sendMsgToUsers...");    
118         for(String jessionId : jsessionSet) 
119             if (users.containsKey(jessionId)) 
120                 users.get(jessionId).sendMessage(new TextMessage(message.getBytes()));
121                 
122 //                ShiroAuthorizationHelper.clearAuthenticationInfo(users.get(jessionId).getId());
123             
124         
125     
126     public void sendMsgToUsers(String message,String jessionId) throws Exception
127         logger.debug("sendMsgToUsers...");    
128         if (users.containsKey(jessionId)) 
129                 users.get(jessionId).sendMessage(new TextMessage(message.getBytes()));
130             
131     
132     /**
133      * 当用户连接ServerSocket时执行
134      * 通过request获取用户登陆的jsessionId的值,放入到集合attributes中
135      */
136     @Override// 
137     public void beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
138             Map<String, Object> attributes) 
139         logger.debug("beforeHandshake...");
140           
141                 if (request instanceof ServletServerHttpRequest)   
142                     ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;  
143                     Cookie cookies[] = servletRequest.getServletRequest().getCookies();
144                     String jsessionId = this.getTicket(cookies);
145                     if (!StringUtils.isNotEmpty(jsessionId)) 
146                         attributes.put(JSESSIONID, this.getTicket(cookies));
147                     
148                   
149              
150             
151     
152     private String getTicket(Cookie cookies[])
153         String jsessionId = null;
154         if(cookies != null)
155             for(Cookie ck: cookies)
156                 if(ck.getName().trim().equals(JSESSIONID))
157                     jsessionId = ck.getValue();
158                     break;
159                 
160             
161         
162         return jsessionId;
163     
164     /**
165      * 当用户连接完ServerSocket时执行
166      */
167     @Override
168     public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
169             Exception ex) 
170         
171         logger.debug("afterHandshake...");
172     
173 
174     public void sendMsgToUsers(String message, List<String> idList) throws Exception
175         logger.debug("sendMsgToUsers...");    
176         for(String jessionId : idList) 
177             if (users.containsKey(jessionId)) 
178                 logger.debug("sendMsgToUsers..."+jessionId);    
179                 users.get(jessionId).sendMessage(new TextMessage(message.getBytes()));
180                 
181             
182         
183         
184     
185 
View Code

4.在具体业务的地方调用

技术图片
1     //向学生端发通知强制退出到首页
2             List<String> userList=sysMessageBaseService.getTrainingUser(usp.getTrainingId());
3             String[] idStr = (String[])userList.toArray(new String[userList.size()]);
4             Set<String> set = new HashSet<String>(Arrays.asList(idStr));
5             userWebsocket.sendMsgToUsers("signOut", set);
View Code
技术图片
 1 String[] idStr = new String[userAccount.size()];
 2         String[] ownId = new String[userAccount.size()];
 3         for (int i = 0; i < userAccount.size(); i++) 
 4             String str = GsonUtils.parseJson(userAccount.get(i));
 5             JSONObject object = JSONObject.fromObject(str);
 6             if (object.getString("organizationCode").equals(partyCode))// 自己方人员
 7             
 8                 ownId[i] = object.getString("userId");
 9              else 
10                 idStr[i] = object.getString("userId");
11             
12 
13         
14         String strMessage = "";
15         String myMessage = "1";
16         if (stateType == CommonEnum.TradingContractStatus.SEND_TERMINATION.getTypeCode()) // 发送终止
17         
18             strMessage="apply;"+contractCode;
19             //strMessage = "对方申请终止" + contractCode + "(合同号),请尽快处理!";
20          else if (stateType == CommonEnum.TradingContractStatus.CONFIRMED.getTypeCode())// 终止不同意
21         
22             strMessage="disagree;"+contractCode;
23             //strMessage = "对方不同意终止" + contractCode + "(合同号),请尽快处理!";
24          else if (stateType == CommonEnum.TradingContractStatus.TERMINATION.getTypeCode())// 终止不同意
25         
26             strMessage="agree;"+contractCode;
27             //strMessage = "对方同意终止" + contractCode + "(合同号),请尽快处理!";
28          else if (stateType == 5)// 终止取消
29         
30             strMessage="cancel;"+contractCode;
31             //strMessage = "对方取消终止" + contractCode + "(合同号),请尽快处理!";
32         
33         infoAndOut(idStr, strMessage); // 对方操作
34         infoAndOut(ownId, myMessage); // 我方刷新数据
View Code

5.websoket.js的引入与在具体页面的实现

技术图片
 1 /**
 2  *  
 3  * @param $
 4  */
 5 (function($) //每页开始直接复制
 6     $.websocket = //外部可以直接访问的对象, 要导入该文件 调用对象$.devfrw.base.demo
 7         connect : function(urlPath,initOpt) //外部可以直接访问的对象的方法, 要导入该文件 调用方法$.devfrw.base.demo.pub
 8                 setUrl(urlPath);
 9                 var opt=onopen:function(),onmessage:function(event),onclose:function(event);
10                 if(initOpt)
11                     opt= $.extend(opt, initOpt);
12                 ;
13                 if (!url)   
14                     alert(‘websocket url 未设置!‘);  
15                     return;  
16                   
17                 ws =new WebSocket(url);  
18                 ws.onopen = function ()   
19                 //    console.log(‘打开链接‘);
20                     opt.onopen();
21                 ;  
22                 ws.onmessage = function (event)   
23                 //    console.log(‘消息接收‘);
24                     opt.onmessage(event);
25                 ;  
26                 ws.onclose = function (event)   
27                 //    console.log(‘关闭链接‘);
28                     opt.onclose(event);
29                 ;  
30         ,
31         setUrl:function(urlPath)
32             setUrl(urlPath);
33         ,
34         send:function(message)
35               if (ws != null)   
36                     ws.send(message);  
37                  else   
38                     alert(‘websocket链接不存在!‘);  
39                   
40         ,
41         disconnect:function()
42             if (ws != null)   
43                 ws.close();  
44                 ws = null;  
45               
46         
47     ;
48     var ws = null;  
49     var url = null;  
50     function setUrl(urlPath)   
51           if (window.location.protocol == ‘http:‘)   
52               url = ‘ws://‘ + window.location.host + urlPath;  
53            else   
54               url = ‘wss://‘ + window.location.host + urlPath;  
55             
56       
57 )(jQuery);//直接复制 一定要;号
View Code
技术图片
 1 $.websocket.connect(‘/portal/websocket.do‘, 
 2         onmessage : function(event) //接收数据 
 3             if(event.data!=""&&event.data!=null)
 4             
 5             if (contains(event.data, "clear")) 
 6                 $(".pay").each(function() 
 7                     var id = $(this).parent().attr("id");
 8                     var salescode = $(this).parent().attr("salescode");
 9                     if (contains(event.data, id + ";"))                         
10                         $("#send" + id).removeClass("disabled");
11                         $("#send" + id).addClass("send");
12                         $("#pay" + id).removeClass("pay");
13                         $("#pay" + id).addClass("disabled");
14                         $("#delete" + id).removeClass("disabled");
15                         $("#delete" + id).attr("onclick","del("+salescode+")");
16                     
17                 );
18             
19             if (contains(event.data, "signOut")) 
20                  layer.msg("轮次结束请返回首页!", 
21                         time: 5000,
22                         shade: 0.6,
23                         success: function (layero, index) 
24                             var msg = layero.text();
25                             var i = 5;
26                             var timer = null;
27                             var fn = function () 
28                                 layero.find(".layui-layer-content").text(msg + ‘(倒计时‘ + i + ‘秒)‘);
29                                 if (!i) 
30                                     layer.close(index);
31                                     clearInterval(timer);
32                                 
33                                 i--;
34                             ;
35                             timer = setInterval(fn, 1000);
36                             fn();
37                         ,
38                     , function () 
39                         window.location.href="$basePathstudent/main/index";
40                     );
41                 
42             
43             
44 
45         ,
46         onclose : function(event)     
47                 $.websocket.disconnect();
48         
49     );
View Code

 

以上是关于websoket在项目中的使用的主要内容,如果未能解决你的问题,请参考以下文章

Vue中使用websoket

SpringBoot2.x整合WebSoket

webSoket的基本使用

Arduino ESP8266 使用Websoket协议通讯网页控制RGB灯

58.websoket实现的客服 实现了发文字消息和图片

Eclipse 中的通用代码片段或模板