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>
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>
<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
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
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
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
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
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);
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); // 我方刷新数据
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);//直接复制 一定要;号
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 );
以上是关于websoket在项目中的使用的主要内容,如果未能解决你的问题,请参考以下文章