最近在项目中,使用到了WebSocket来实时推送服务器的数据到客户端,今天来记录总结一下。
想要使用WebSocket来实时推送数据,首先需要服务器与客户端直接建立连接,也就是握手(HTTP协议)
每5秒钟发生一个心跳
@Scheduled(cron = "0/5 * * * * ? ") public void sendHeart() { MessageWebSocket.broadcast(new WebSocketMessage(WebSocketMessage.CMD_HEART, "SUCCESS")); }
后端重要的代码:
ServerEndpoint("/ws/{userId}") @Component @Slf4j public class MessageWebSocket { /** * concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象. */ private static Map<String, MessageWebSocket> mapUserId = new ConcurrentHashMap<>(); /** * 与某个客户端的连接会话,需要通过它来给客户端发送数据. */ private Session session; /** * 接收userId. */ private String userId = ""; /** * . 连接建立成功调用的方法 */ @OnOpen public void onOpen(Session session, @PathParam("userId") String userId) { this.session = session; this.userId = userId; mapUserId.put(userId, this); log.info("用户连接:" + userId); try { send(JSON.toJSONString(new WebSocketMessage(WebSocketMessage.CMD_CONN, "SUCCESS"))); } catch (IOException e) { e.printStackTrace(); log.error("用户:" + userId + ",网络异常!!!!!!"); } } /** * . 连接关闭调用的方法 */ @OnClose public void onClose() { mapUserId.remove(userId); } /** * . 收到客户端消息后调用的方法 * * @param message 客户端发送过来的消息 */ @OnMessage public void onMessage(String message, Session session) { log.info("user id:" + userId + ",message:" + message); } /** * . * * @param session 回话 * @param error 错误信息 */ @OnError public void onError(Session session, Throwable error) { log.error("user id:" + this.userId + ",reason:" + error.getMessage()); error.printStackTrace(); } /** * . 实现服务器主动推送 */ public void send(String message) throws IOException { if (this.session != null) { synchronized (session) { this.session.getBasicRemote().sendText(message); } } } /** * . 实现服务器主动推送 */ public static void send(String userId, String message) throws IOException { MessageWebSocket socket = mapUserId.get(userId); if (socket != null) { try { socket.send(message); } catch (IOException e) { e.printStackTrace(); } } } /** * 广播发送. * * @param message webSocket消息 */ public static void broadcast(WebSocketMessage message) { if (null == message) { return; } String content = JSON.toJSONString(message); //log.info("message :{}", content); for (String userId : mapUserId.keySet()) { try { send(userId, content); } catch (IOException e) { e.printStackTrace(); } } } }
前端代码(VUE):百度搜索前端连接WebSocket
methods: { initWebSocket() { //初始化weosocket const wsuri = "ws://127.0.0.1:8080"; this.websock = new WebSocket(wsuri); this.websock.onmessage = this.websocketonmessage; this.websock.onopen = this.websocketonopen; this.websock.onerror = this.websocketonerror; this.websock.onclose = this.websocketclose; }, websocketonopen() { //连接建立之后执行send方法发送数据 let actions = { "test": "123" }; this.websocketsend(JSON.stringify(actions)); }, websocketonerror() { //连接建立失败重连 this.initWebSocket(); }, websocketonmessage(e) { //数据接收 const redata = JSON.parse(e.data); }, websocketsend(Data) { //数据发送 this.websock.send(Data); }, websocketclose(e) { //关闭 console.log('断开连接', e); }, }