1、pom.xml額外增加依賴
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-websocket</artifactId> <version>${spring.version}</version> </dependency>
2、自定義JoyinMessageHandler繼承WebSocketHandler,處理消息
/* * 文件名:JoyinMessageHandler.java * 版權:Copyright 2016-2017 JoyinTech. Co. Ltd. All Rights Reserved. * 描述:中信銀行資管系統 * 修改人:Administrator * 修改時間:2020年1月16日 * 修改內容:新建 * 系統名稱:中信銀行資管系統 */ package com.joyintech.tams.framework; import java.io.IOException; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; 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; /** * 〈一句話功能簡述〉 〈功能詳細描述〉 * * @author Administrator * @version 1.0 2020年1月16日 * @see JoyinMessageHandler * @since 1.0 */ @Component public class JoyinMessageHandler implements WebSocketHandler { /** * 用戶 */ public static final String USER_KEY = "socket_user"; /** * 用戶數量 */ private final static int size = 300; /** * userMap:存儲用戶連接webscoket信息 * * @since JDK 1.7 */ private final static Map<String, WebSocketSession> userMap; static { userMap = new ConcurrentHashMap<String, WebSocketSession>(size); } @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception { String userId = this.getUserId(session); if (!StringUtils.isEmpty(userId)) { userMap.remove(userId); System.err.println(userId + "用戶已成功關閉會話"); } else { System.err.println("關閉時,獲取用戶id為空"); } } @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { String userId = this.getUserId(session); if (!StringUtils.isEmpty(userId)) { userMap.put(userId, session); } } @Override public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception { String msg = message.toString(); String userId = this.getUserId(session); System.err.println("該" + userId + "用戶發送的消息是:" + msg); message = new TextMessage("服務端已經接收到消息,msg=" + msg); session.sendMessage(message); } @Override public void handleTransportError(WebSocketSession session, Throwable e) throws Exception { WebSocketMessage<String> message = new TextMessage("異常信息:" + e.getMessage()); session.sendMessage(message); } @Override public boolean supportsPartialMessages() { return false; } private String getUserId(WebSocketSession session) { try { String userId = (String)session.getAttributes().get(USER_KEY); return userId; } catch (Exception e) { e.printStackTrace(); } return null; } /** * 給某個用戶發送消息 * * @param userId * @param message */ public void sendMessageToUser(String userId, TextMessage message) { WebSocketSession webSocketSession = userMap.get(userId); if (webSocketSession != null && webSocketSession.isOpen()) { try { webSocketSession.sendMessage(message); } catch (IOException e) { e.printStackTrace(); } } } }
3、編寫攔截器WebSocketInterceptor繼承HttpSessionHandshakeInterceptor實現用戶的綁定
/* * 文件名:WebSocketInterceptor.java * 版權:Copyright 2016-2017 JoyinTech. Co. Ltd. All Rights Reserved. * 描述:中信銀行資管系統 * 修改人:Administrator * 修改時間:2020年1月16日 * 修改內容:新建 * 系統名稱:中信銀行資管系統 */ package com.joyintech.tams.framework.interceptor; import java.util.Map; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; import org.springframework.http.server.ServletServerHttpRequest; import org.springframework.web.socket.WebSocketHandler; import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor; import com.joyintech.tams.framework.JoyinMessageHandler; /** * 〈一句話功能簡述〉 〈功能詳細描述〉 * * @author Administrator * @version 1.0 2020年1月16日 * @see WebSocketInterceptor * @since 1.0 */ public class WebSocketInterceptor extends HttpSessionHandshakeInterceptor { /** * TODO 描述該方法的實現功能. * * @see org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor#beforeHandshake(org.springframework.http.server.ServerHttpRequest, * org.springframework.http.server.ServerHttpResponse, * org.springframework.web.socket.WebSocketHandler, java.util.Map) */ @Override public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception { if (request instanceof ServletServerHttpRequest) { ServletServerHttpRequest serverHttpRequest = (ServletServerHttpRequest)request; // 獲取參數 String userId = serverHttpRequest.getServletRequest().getParameter("userId"); attributes.put(JoyinMessageHandler.USER_KEY, userId); } return true; } }
4、修改spring配置文件,增加以下配置
<!-- 配置webSockte --> <websocket:handlers allowed-origins="*"> <!-- 前端握手請求地址 --> <websocket:mapping path="/socketServer" handler="joyinMessageHandler"/> <websocket:handshake-interceptors> <bean class="com.joyintech.tams.framework.interceptor.WebSocketInterceptor"/> </websocket:handshake-interceptors> </websocket:handlers>
5、修改js增加以下方法
var homepage = function() { return { /** * 綁定用戶信息 */ bindUserInfo : function() { if('WebSocket' in window) { var websocket = new WebSocket("ws://"+baseFullPath+"socketServer?userId="+loginUserId); // 打開連接時 websocket.onopen = function(evnt) { console.log("websocket已啟用"); }; // 收到消息時 websocket.onmessage = function(message) { console.log("收到websocket消息:" + message.data); }; //出錯時 websocket.onerror = function(evnt) { console.log("與后台握手出現問題!"); }; //關閉時 websocket.onclose = function(evnt) { console.log("正在關閉 webSocket "); }; } }, } }(); jQuery(document).ready(function() { // 綁定用戶信息 homepage.bindUserInfo(); })
6、修改jsp獲得baseFullPath
<% String path = request.getContextPath(); String baseFullPath = request.getServerName() + ":" + request.getServerPort() + path + "/"; %> <script type="text/javascript"> var baseFullPath = '<%=baseFullPath%>'; var loginUserId = '${user.userId}'; </script>
7、在任意地方調用com.joyintech.tams.framework.JoyinMessageHandler.sendMessageToUser(String, TextMessage)方法即可
messageHandler.sendMessageToUser("00000000000000000002", new TextMessage("發送消息給用戶00000000000000000002"));
