zoukankan      html  css  js  c++  java
  • 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="${basePath}student/main/index";
    40                     });
    41                 
    42             }
    43             }
    44 
    45         },
    46         onclose : function(event) {    
    47                 $.websocket.disconnect();
    48         }
    49     });
    View Code
  • 相关阅读:
    第四次上课 PPT作业
    大道至简 读后感④
    第三次上课 PPT 课后测试
    大道至简 读后感③
    Java 02 课后作业
    Java 多个数字相加算法
    大道至简 读后感②
    wpf控件
    一个简单的prism mef例子
    c#弱事件(weak event)
  • 原文地址:https://www.cnblogs.com/songStar/p/11022501.html
Copyright © 2011-2022 走看看