package com.mes.tools; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.stereotype.Component; import javax.websocket.*; import javax.websocket.server.PathParam; import javax.websocket.server.ServerEndpoint; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @ServerEndpoint(value = "/api/talk/{username}") @Component("webSocketServer") public class WebSocketServer { // @Autowired // HomeMapper homeMapper; public static ConfigurableApplicationContext applicationContext; // 解决无法注入mapper问题 //使用方法 // homeMapper=WebSocketServer.applicationContext.getBean(HomeMapper.class); public static void setApplicationContext(ConfigurableApplicationContext configurableApplicationContext) { WebSocketServer.applicationContext = configurableApplicationContext; } private static final Logger log = LoggerFactory.getLogger(WebSocketServer.class); private List messages; /** * 记录当前在线连接数 */ public static final Map> sessionMap = new ConcurrentHashMap<>(); String username; Session session; public WebSocketServer() { this.messages = new ArrayList<>(); } /** * 连接建立成功调用的方法 */ @OnOpen public void onOpen(Session session, @PathParam("username") String username) { this.username = username; this.session = session; List webSocketServers = sessionMap.get(username); if (webSocketServers == null) { ArrayList arrayListwebserver = new ArrayList(); arrayListwebserver.add(this); sessionMap.put(username, arrayListwebserver); } else { webSocketServers.add(this); } log.info("有新用户加入,username={}, 当前在线人数为:{}", username, sessionMap.get(username).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); // array.add(jsonObject); // } // sendAllMessage(JSONUtil.toJsonStr(result)); // 后台发送消息给所有的客户端 } /** * 连接关闭调用的方法 */ @OnClose public void onClose(Session session, @PathParam("username") String username) { List webSocketServers = sessionMap.get(username); ArrayList arrayListwebserver = new ArrayList(); if (webSocketServers.size() > 1) { for (WebSocketServer webSocketServer : webSocketServers) { if (webSocketServer != this) { arrayListwebserver.add(webSocketServer); } } sessionMap.put(username, arrayListwebserver); log.info("移除username={}一名用户session, {}的当前在线人数为:{}", username, username, sessionMap.get(username).size()); } else { sessionMap.remove(username); log.info("移除username={}一名用户session, {}连接关闭, 当前连接数为:{}", username, 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 text = obj.getStr("data"); JSONObject jsonObject = new JSONObject(); jsonObject.set("message", text); this.messages.add(text); this.sendMessage(jsonObject.toString()); // JSONUtil.toJsonStr(jsonObject) } @OnError public void onError(Session session, Throwable error) { log.error("发生错误"); error.printStackTrace(); } /** * 服务端发送消息给客户端 */ public void sendMessage(String message) { try { // log.info("服务端给客户端[{}]发送消息{}", this.session.getId(), message); this.session.getBasicRemote().sendText(message); } catch (Exception e) { log.error("服务端发送消息给客户端失败", e); } } // /** // * 服务端发送消息给所有客户端 // */ // public void sendAllMessage(String message) { // try { // for (WebSocketServer webSocketServer : sessionMap.values()) { // // log.info("服务端给客户端[{}]发送消息{}", this.session.getId(), message); // webSocketServer.sendMessage(message); // } // } catch (Exception e) { // log.error("服务端发送消息给客户端失败", e); // } // } public List getMessages() { return messages; } public void clearMessages() { messages.clear(); } }