PublicScreenChatWebsocket.java 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. package com.izouma.nineth.websocket;
  2. import com.alibaba.fastjson.JSON;
  3. import com.izouma.nineth.domain.PublicScreenChat;
  4. import com.izouma.nineth.domain.PurchaseLevel;
  5. import com.izouma.nineth.domain.User;
  6. import com.izouma.nineth.dto.PublicScreenChatExceptionMsg;
  7. import com.izouma.nineth.exception.BusinessException;
  8. import com.izouma.nineth.repo.PublicScreenChatRepo;
  9. import com.izouma.nineth.repo.UserRepo;
  10. import com.izouma.nineth.service.ContentAuditService;
  11. import com.izouma.nineth.service.PurchaseLevelService;
  12. import com.izouma.nineth.utils.ApplicationContextUtil;
  13. import lombok.extern.slf4j.Slf4j;
  14. import org.apache.commons.lang3.StringUtils;
  15. import org.springframework.stereotype.Service;
  16. import javax.websocket.*;
  17. import javax.websocket.server.PathParam;
  18. import javax.websocket.server.ServerEndpoint;
  19. import java.time.LocalDateTime;
  20. import java.util.Map;
  21. import java.util.Objects;
  22. import java.util.Set;
  23. import java.util.concurrent.ConcurrentHashMap;
  24. @Service
  25. @ServerEndpoint(value = "/websocket/public/screen/{nickName}/{userId}")
  26. @Slf4j
  27. public class PublicScreenChatWebsocket extends WebsocketCommon {
  28. /**
  29. * 当前在线的客户端map
  30. */
  31. private static final Map<String, Session> clients = new ConcurrentHashMap();
  32. private PublicScreenChatRepo publicScreenChatRepo;
  33. private final String PREFIX = "meta-chat:";
  34. private UserRepo userRepo;
  35. private PurchaseLevelService purchaseLevelService;
  36. private ContentAuditService contentAuditService;
  37. private void init() {
  38. if (Objects.isNull(publicScreenChatRepo)) {
  39. publicScreenChatRepo = (PublicScreenChatRepo) ApplicationContextUtil.getBean("publicScreenChatRepo");
  40. }
  41. if (Objects.isNull(userRepo)) {
  42. userRepo = (UserRepo) ApplicationContextUtil.getBean("userRepo");
  43. }
  44. if (Objects.isNull(purchaseLevelService)) {
  45. purchaseLevelService = (PurchaseLevelService) ApplicationContextUtil.getBean("purchaseLevelService");
  46. }
  47. if (Objects.isNull(contentAuditService)) {
  48. contentAuditService = (ContentAuditService) ApplicationContextUtil.getBean("contentAuditService");
  49. }
  50. }
  51. @OnOpen
  52. public void onOpen(@PathParam("nickName") String nickName, @PathParam("userId") String userId, Session session) {
  53. init();
  54. // 判断当前玩家是否在其他地方登陆
  55. if (clients.containsKey(PREFIX.concat(userId))) {
  56. String msg = String.format("已在别处登陆,sessionId为[%S],正在为您关闭本连接", session.getId());
  57. exceptionHandle(userId, new PublicScreenChatExceptionMsg(1, msg));
  58. try {
  59. log.info("关闭session连接");
  60. clients.get(PREFIX.concat(userId)).close();
  61. } catch (Exception e) {
  62. exceptionHandle(userId, new PublicScreenChatExceptionMsg(1, String.format("session close throw exception[%S]", e)));
  63. return;
  64. }
  65. }
  66. log.info("现在来连接的sessionId:" + session.getId() + "玩家id:" + userId + "玩家昵称" + nickName);
  67. clients.put(PREFIX.concat(userId), session);
  68. String format = String.format("玩家[%S][%S]进入大厅", userId, nickName);
  69. PublicScreenChat publicScreenChat;
  70. try {
  71. publicScreenChat = savePublicScreenChat(userId, format, true);
  72. } catch (Exception e) {
  73. String errMsg = String.format("玩家进入大厅,保存信息发生异常[%S]", e);
  74. exceptionHandle(userId, new PublicScreenChatExceptionMsg(2, errMsg));
  75. return;
  76. }
  77. sendMessageToOther(clients, JSON.toJSONString(publicScreenChat), PREFIX.concat(userId));
  78. }
  79. @OnError
  80. public void onError(Session session, Throwable error) {
  81. // 异常处理
  82. log.error(String.format("sessionId[%S]的服务端发生了错误:[%S]", session.getId(), error.getMessage()));
  83. }
  84. @OnClose
  85. public void onClose(@PathParam("nickName") String nickName, @PathParam("userId") String userId, Session session) {
  86. init();
  87. log.info(String.format("sessionId:[%S] userId:[%S] is closed", session.getId(), userId));
  88. String format = String.format("玩家[%S][%S]离开大厅", userId, nickName);
  89. PublicScreenChat publicScreenChat;
  90. try {
  91. publicScreenChat = savePublicScreenChat(userId, format, true);
  92. } catch (Exception e) {
  93. String errMsg = String.format("玩家离开大厅,保存信息发生异常[%S]", e);
  94. exceptionHandle(userId, new PublicScreenChatExceptionMsg(2, errMsg));
  95. return;
  96. }
  97. sendMessageToOther(clients, JSON.toJSONString(publicScreenChat), PREFIX.concat(userId));
  98. clients.remove(PREFIX.concat(userId));
  99. }
  100. @OnMessage
  101. public void onMessage(@PathParam("userId") String userId, String message) {
  102. init();
  103. if (StringUtils.isBlank(message)) {
  104. String errMsg = "Illegal parameter : message can not be null";
  105. exceptionHandle(userId, new PublicScreenChatExceptionMsg(4, errMsg));
  106. return;
  107. }
  108. if (!contentAuditService.auditText(message)) {
  109. savePublicScreenChat(userId, message, false);
  110. exceptionHandle(userId, new PublicScreenChatExceptionMsg(3, "消息包含非法内容"));
  111. return;
  112. }
  113. PublicScreenChat publicScreenChat;
  114. try {
  115. publicScreenChat = savePublicScreenChat(userId, message, true);
  116. } catch (Exception e) {
  117. String errMsg = String.format("玩家发送消息,保存信息发生异常[%S]", e);
  118. exceptionHandle(userId, new PublicScreenChatExceptionMsg(2, errMsg));
  119. return;
  120. }
  121. sendMessageToAll(clients, JSON.toJSONString(publicScreenChat), PREFIX.concat(userId));
  122. }
  123. /**
  124. * 给所有用户发消息
  125. *
  126. * @param clients 在线客户端
  127. * @param message 消息
  128. */
  129. public void sendMessageToAll(Map<String, Session> clients, String message, String userId) {
  130. PublicScreenChat publicScreenChat = JSON.parseObject(message, PublicScreenChat.class);
  131. Set<String> userIds = clients.keySet();
  132. userIds.forEach(id -> {
  133. try {
  134. publicScreenChat.setMyself(id.equals(userId));
  135. log.info(String.format("服务器给所有在线用户发送消息,当前在线人员为[%S]。消息:[%S]", id, JSON.toJSONString(publicScreenChat)));
  136. clients.get(id).getBasicRemote().sendText(JSON.toJSONString(publicScreenChat));
  137. } catch (Exception e) {
  138. log.error(String.format("send message [%S] to [%S] throw exception [%S]:", JSON.toJSONString(publicScreenChat), id, e));
  139. }
  140. });
  141. }
  142. private PublicScreenChat savePublicScreenChat(String userId, String messageInfo, boolean illegal) {
  143. User user = userRepo.findById(Long.parseLong(userId)).orElse(null);
  144. if (Objects.isNull(user)) {
  145. throw new BusinessException("用户信息不存在");
  146. }
  147. PublicScreenChat publicScreenChat = new PublicScreenChat();
  148. publicScreenChat.setUserId(userId);
  149. publicScreenChat.setAvatar(user.getAvatar());
  150. publicScreenChat.setNickname(user.getNickname());
  151. publicScreenChat.setLevel(user.getLevel());
  152. PurchaseLevel purchaseLevel = purchaseLevelService.findPurchaseLevelByLevel(publicScreenChat.getLevel());
  153. publicScreenChat.setRealm(purchaseLevel.getRealm());
  154. publicScreenChat.setTitle(purchaseLevel.getTitle());
  155. publicScreenChat.setMessageInfo(messageInfo);
  156. publicScreenChat.setTime(LocalDateTime.now());
  157. publicScreenChat.setIllegal(illegal);
  158. return publicScreenChatRepo.save(publicScreenChat);
  159. }
  160. private void exceptionHandle(String userId, PublicScreenChatExceptionMsg msg) {
  161. log.error(JSON.toJSONString(msg));
  162. // 推送消息给该玩家
  163. sendMessageTo(clients, JSON.toJSONString(msg), PREFIX.concat(userId));
  164. }
  165. }