MessageWebsocket.java 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. package com.java110.api.websocket;
  2. import com.alibaba.fastjson.JSONObject;
  3. import com.java110.dto.WsDataDto;
  4. import com.java110.utils.util.StringUtil;
  5. import com.java110.vo.ResultVo;
  6. import org.slf4j.Logger;
  7. import org.slf4j.LoggerFactory;
  8. import org.springframework.stereotype.Component;
  9. import javax.websocket.OnClose;
  10. import javax.websocket.OnError;
  11. import javax.websocket.OnMessage;
  12. import javax.websocket.OnOpen;
  13. import javax.websocket.Session;
  14. import javax.websocket.server.PathParam;
  15. import javax.websocket.server.ServerEndpoint;
  16. import java.io.IOException;
  17. import java.util.concurrent.ConcurrentHashMap;
  18. /**
  19. * @ClassName MessageWebsocket
  20. * @Description TODO
  21. * @Author wuxw
  22. * @Date 2020/6/5 12:16
  23. * @Version 1.0
  24. * add by wuxw 2020/6/5
  25. **/
  26. @ServerEndpoint("/ws/message/{userId}")
  27. @Component
  28. public class MessageWebsocket {
  29. private final static Logger logger = LoggerFactory.getLogger(MessageWebsocket.class);
  30. /**
  31. * 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
  32. */
  33. private static int onlineCount = 0;
  34. /**
  35. * concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
  36. */
  37. private static ConcurrentHashMap<String, MessageWebsocket> webSocketMap = new ConcurrentHashMap<>();
  38. /**
  39. * concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
  40. */
  41. private static ConcurrentHashMap<String, String> clientMachineMap = new ConcurrentHashMap<>();
  42. /**
  43. * 与某个客户端的连接会话,需要通过它来给客户端发送数据
  44. */
  45. private Session session;
  46. /**
  47. * 接收clientId
  48. */
  49. private String userId = "";
  50. /**
  51. * 连接建立成功调用的方法
  52. */
  53. @OnOpen
  54. public void onOpen(Session session, @PathParam("userId") String userId) {
  55. this.session = session;
  56. this.userId = userId;
  57. if (webSocketMap.containsKey(userId)) {
  58. webSocketMap.remove(userId);
  59. webSocketMap.put(userId, this);
  60. //加入set中
  61. } else {
  62. webSocketMap.put(userId, this);
  63. //加入set中
  64. addOnlineCount();
  65. //在线数加1
  66. }
  67. logger.debug("用户连接:" + userId + ",当前在线人数为:" + getOnlineCount());
  68. try {
  69. sendMessage("连接成功");
  70. } catch (IOException e) {
  71. logger.error("用户:" + userId + ",网络异常!!!!!!");
  72. }
  73. }
  74. /**
  75. * 连接关闭调用的方法
  76. */
  77. @OnClose
  78. public void onClose() {
  79. if (webSocketMap.containsKey(userId)) {
  80. webSocketMap.remove(userId);
  81. //从set中删除
  82. subOnlineCount();
  83. }
  84. logger.info("用户退出:" + userId + ",当前在线人数为:" + getOnlineCount());
  85. }
  86. /**
  87. * 收到客户端消息后调用的方法
  88. *
  89. * @param message 客户端发送过来的消息
  90. */
  91. @OnMessage
  92. public void onMessage(String message, Session session) throws IOException {
  93. logger.info("用户消息:" + userId + ",报文:" + message);
  94. //可以群发消息
  95. //消息保存到数据库、redis
  96. if (StringUtil.isEmpty(message)) {
  97. ResultVo resultVo = new ResultVo(ResultVo.CODE_ERROR, "未包含内容");
  98. webSocketMap.get(userId).sendMessage(resultVo.toString());
  99. return;
  100. }
  101. if (!StringUtil.isJsonObject(message)) {
  102. ResultVo resultVo = new ResultVo(ResultVo.CODE_ERROR, "不是有效数据格式");
  103. webSocketMap.get(userId).sendMessage(resultVo.toString());
  104. return;
  105. }
  106. WsDataDto wsDataDto = JSONObject.parseObject(message, WsDataDto.class);
  107. switch (wsDataDto.getCmd()){
  108. case WsDataDto.CMD_PING:
  109. webSocketMap.get(userId).sendMessage(wsDataDto.toString());
  110. break;
  111. }
  112. // //解析发送的报文
  113. // JSONObject jsonObject = JSONObject.parseObject(message);
  114. // //追加发送人(防止串改)
  115. // jsonObject.put("fromUserId", this.userId);
  116. // String toUserId = jsonObject.getString("toUserId");
  117. // //传送给对应toUserId用户的websocket
  118. // if (!StringUtil.isEmpty(toUserId) && webSocketMap.containsKey(toUserId)) {
  119. // webSocketMap.get(toUserId).sendMessage(jsonObject.toJSONString());
  120. // } else {
  121. // logger.error("请求的clientId:" + toUserId + "不在该服务器上");
  122. // //否则不在这个服务器上,发送到mysql或者redis
  123. // }
  124. }
  125. /**
  126. * @param session
  127. * @param error
  128. */
  129. @OnError
  130. public void onError(Session session, Throwable error) {
  131. logger.error("用户错误:" + this.userId + ",原因:" + error.getMessage());
  132. error.printStackTrace();
  133. }
  134. /**
  135. * 实现服务器主动推送
  136. */
  137. public void sendMessage(String message) throws IOException {
  138. this.session.getBasicRemote().sendText(message);
  139. }
  140. /**
  141. * 发送设备监控信息
  142. */
  143. public static void sendInfo(String message, String userId) throws IOException {
  144. logger.info("发送消息到:" + userId + ",报文:" + message);
  145. webSocketMap.get(userId).sendMessage(message);
  146. }
  147. public static synchronized int getOnlineCount() {
  148. return onlineCount;
  149. }
  150. public static synchronized void addOnlineCount() {
  151. MessageWebsocket.onlineCount++;
  152. }
  153. public static synchronized void subOnlineCount() {
  154. MessageWebsocket.onlineCount--;
  155. }
  156. }