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"));