| package com.zy.common.config; | 
|   | 
| import cn.hutool.json.JSONArray; | 
| import cn.hutool.json.JSONObject; | 
| import cn.hutool.json.JSONUtil; | 
| import org.slf4j.Logger; | 
| import org.slf4j.LoggerFactory; | 
| import org.springframework.stereotype.Component; | 
| import org.springframework.stereotype.Service; | 
|   | 
| import javax.websocket.*; | 
| import javax.websocket.server.PathParam; | 
| import javax.websocket.server.ServerEndpoint; | 
| import java.util.Map; | 
| import java.util.concurrent.ConcurrentHashMap; | 
|   | 
| @ServerEndpoint(value = "/led/{username}") | 
| @Component | 
| @Service | 
| public class WebSocketServer { | 
|     private static final Logger log = LoggerFactory.getLogger(WebSocketServer.class); | 
|     /** | 
|      * 记录当前在线连接数 | 
|      */ | 
|     public static final Map<String, Session> sessionMap = new ConcurrentHashMap<>(); | 
|     /** | 
|      * 连接建立成功调用的方法 | 
|      */ | 
|     @OnOpen | 
|     public void onOpen(Session session, @PathParam("username") String username) { | 
|         sessionMap.put(username, session); | 
|         log.info("有新用户加入,username={}, 当前在线人数为:{}", username, sessionMap.size()); | 
|         JSONObject result = new JSONObject(); | 
|         JSONArray array = new JSONArray(); | 
|         result.set("users", array); | 
|         for (Object key : sessionMap.keySet()) { | 
|             JSONObject jsonObject = new JSONObject(); | 
|             jsonObject.set("username", key); | 
|             // {"username", "zhang", "username": "admin"} | 
|             array.add(jsonObject); | 
|         } | 
| //        {"users": [{"username": "zhang"},{ "username": "admin"}]} | 
|         sendAllMessage(JSONUtil.toJsonStr(result));  // 后台发送消息给所有的客户端 | 
|     } | 
|     /** | 
|      * 连接关闭调用的方法 | 
|      */ | 
|     @OnClose | 
|     public void onClose(Session session, @PathParam("username") String username) { | 
|         sessionMap.remove(username); | 
|         log.info("有一连接关闭,移除username={}的用户session, 当前在线人数为:{}", username, sessionMap.size()); | 
|     } | 
|     /** | 
|      * 收到客户端消息后调用的方法 | 
|      * 后台收到客户端发送过来的消息 | 
|      * onMessage 是一个消息的中转站 | 
|      * 接受 浏览器端 socket.send 发送过来的 json数据 | 
|      * @param message 客户端发送过来的消息 | 
|      */ | 
|     @OnMessage | 
|     public void onMessage(String message, Session session, @PathParam("username") String username) { | 
| //        log.info("服务端收到用户username={}的消息:{}", username, message); | 
|         JSONObject obj = JSONUtil.parseObj(message); | 
|         String toUsername = obj.getStr("to"); // to表示发送给哪个用户,比如 admin | 
|         String text = obj.getStr("message"); // 发送的消息文本  hello | 
|         // {"to": "admin", "text": "聊天文本"} | 
|         if ("heartBeat".equals(toUsername)) { | 
|             log.info("心跳"); | 
|         }else if ("all".equals(toUsername)) { | 
|             sendAllMessage(text); | 
|         }else { | 
|             Session toSession = sessionMap.get(toUsername); // 根据 to用户名来获取 session,再通过session发送消息文本 | 
|             if (toSession != null) { | 
|                 // 服务器端 再把消息组装一下,组装后的消息包含发送人和发送的文本内容 | 
|                 // {"from": "zhang", "text": "hello"} | 
|                 JSONObject jsonObject = new JSONObject(); | 
|                 jsonObject.set("from", username);  // from 是 zhang | 
|                 jsonObject.set("text", text);  // text 同上面的text | 
|                 this.sendMessage(text, toSession); | 
| //            log.info("发送给用户username={},消息:{}", toUsername, jsonObject.toString()); | 
|             } else { | 
| //                log.info("发送失败,未找到用户username={}的session", toUsername); | 
|             } | 
|         } | 
|   | 
|     } | 
|     @OnError | 
|     public void onError(Session session, Throwable error) { | 
|         log.error("发生错误"); | 
|         error.printStackTrace(); | 
|     } | 
|     /** | 
|      * 服务端发送消息给客户端 | 
|      */ | 
|     private void sendMessage(String message, Session toSession) { | 
|         try { | 
| //            log.info("服务端给客户端[{}]发送消息{}", toSession.getId(), message); | 
|             toSession.getBasicRemote().sendText(message); | 
|         } catch (Exception e) { | 
|             log.error("服务端发送消息给客户端失败", e); | 
|         } | 
|     } | 
|     /** | 
|      * 服务端发送消息给所有客户端 | 
|      */ | 
|     private void sendAllMessage(String message) { | 
|         try { | 
|             for (Session session : sessionMap.values()) { | 
| //                log.info("服务端给客户端[{}]发送消息{}", session.getId(), message); | 
|                 session.getBasicRemote().sendText(message); | 
|             } | 
|         } catch (Exception e) { | 
|             log.error("服务端发送消息给客户端失败", e); | 
|         } | 
|     } | 
| } |