利用websocket,注入依赖service的bean为null

打印 上一主题 下一主题

主题 1032|帖子 1032|积分 3096

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
标题:依赖注入失败,service获取不到,提示null
这是参考代码
  1. package com.shier.ws;
  2. import cn.hutool.core.date.DateUtil;
  3. import cn.hutool.json.JSONObject;
  4. import cn.hutool.json.JSONUtil;
  5. import com.google.gson.Gson;
  6. import com.shier.config.HttpSessionConfig;
  7. import com.shier.model.domain.Chat;
  8. import com.shier.model.domain.Team;
  9. import com.shier.model.domain.User;
  10. import com.shier.model.request.MessageRequest;
  11. import com.shier.model.vo.ChatMessageVO;
  12. import com.shier.model.vo.WebSocketVO;
  13. import com.shier.service.ChatService;
  14. import com.shier.service.TeamService;
  15. import com.shier.service.UserService;
  16. import lombok.extern.slf4j.Slf4j;
  17. import org.apache.commons.lang3.StringUtils;
  18. import org.springframework.beans.BeanUtils;
  19. import org.springframework.stereotype.Component;
  20. import javax.annotation.Resource;
  21. import javax.servlet.http.HttpSession;
  22. import javax.websocket.*;
  23. import javax.websocket.server.PathParam;
  24. import javax.websocket.server.ServerEndpoint;
  25. import java.io.IOException;
  26. import java.io.Serializable;
  27. import java.util.*;
  28. import java.util.concurrent.ConcurrentHashMap;
  29. import java.util.concurrent.CopyOnWriteArraySet;
  30. import static com.shier.constants.ChatConstant.*;
  31. import static com.shier.constants.UserConstants.ADMIN_ROLE;
  32. import static com.shier.constants.UserConstants.USER_LOGIN_STATE;
  33. /**
  34. * WebSocket服务
  35. */
  36. @Component
  37. @Slf4j
  38. @ServerEndpoint(value = "/websocket/{userId}/{teamId}", configurator = HttpSessionConfig.class)
  39. public class WebSocket {
  40.     /**
  41.      * 保存队伍的连接信息
  42.      */
  43.     private static final Map<String, ConcurrentHashMap<String, WebSocket>> ROOMS = new HashMap<>();
  44.     /**
  45.      * 线程安全的无序的集合
  46.      */
  47.     private static final CopyOnWriteArraySet<Session> SESSIONS = new CopyOnWriteArraySet<>();
  48.     /**
  49.      * 会话池
  50.      */
  51.     private static final Map<String, Session> SESSION_POOL = new HashMap<>(0);
  52.     /**
  53.      * 用户服务
  54.      */
  55.     private static UserService userService;
  56.     /**
  57.      * 聊天服务
  58.      */
  59.     private static ChatService chatService;
  60.     /**
  61.      * 团队服务
  62.      */
  63.     private static TeamService teamService;
  64.     /**
  65.      * 房间在线人数
  66.      */
  67.     private static int onlineCount = 0;
  68.     /**
  69.      * 当前信息
  70.      */
  71.     private Session session;
  72.     /**
  73.      * http会话
  74.      */
  75.     private HttpSession httpSession;
  76.     /**
  77.      * 上网数
  78.      *
  79.      * @return int
  80.      */
  81.     public static synchronized int getOnlineCount() {
  82.         return onlineCount;
  83.     }
  84.     /**
  85.      * 添加在线计数
  86.      */
  87.     public static synchronized void addOnlineCount() {
  88.         WebSocket.onlineCount++;
  89.     }
  90.     /**
  91.      * 子在线计数
  92.      */
  93.     public static synchronized void subOnlineCount() {
  94.         WebSocket.onlineCount--;
  95.     }
  96.     /**
  97.      * 集热地图服务
  98.      *
  99.      * @param userService 用户服务
  100.      */
  101.     @Resource
  102.     public void setHeatMapService(UserService userService) {
  103.         WebSocket.userService = userService;
  104.     }
  105.     /**
  106.      * 集热地图服务
  107.      *
  108.      * @param chatService 聊天服务
  109.      */
  110.     @Resource
  111.     public void setHeatMapService(ChatService chatService) {
  112.         WebSocket.chatService = chatService;
  113.     }
  114.     /**
  115.      * 集热地图服务
  116.      *
  117.      * @param teamService 团队服务
  118.      */
  119.     @Resource
  120.     public void setHeatMapService(TeamService teamService) {
  121.         WebSocket.teamService = teamService;
  122.     }
  123.     /**
  124.      * 队伍内群发消息
  125.      *
  126.      * @param teamId 团队id
  127.      * @param msg    消息
  128.      */
  129.     public static void broadcast(String teamId, String msg) {
  130.         ConcurrentHashMap<String, WebSocket> map = ROOMS.get(teamId);
  131.         // keySet获取map集合key的集合  然后在遍历key即可
  132.         for (String key : map.keySet()) {
  133.             try {
  134.                 WebSocket webSocket = map.get(key);
  135.                 webSocket.sendMessage(msg);
  136.             } catch (Exception e) {
  137.                 e.printStackTrace();
  138.             }
  139.         }
  140.     }
  141.     /**
  142.      * 发送消息
  143.      *
  144.      * @param message 消息
  145.      * @throws IOException ioexception
  146.      */
  147.     public void sendMessage(String message) throws IOException {
  148.         this.session.getBasicRemote().sendText(message);
  149.     }
  150.     /**
  151.      * 开放
  152.      *
  153.      * @param session 会话
  154.      * @param userId  用户id
  155.      * @param teamId  团队id
  156.      * @param config  配置
  157.      */
  158.     @OnOpen
  159.     public void onOpen(Session session, @PathParam(value = "userId") String userId, @PathParam(value = "teamId") String teamId, EndpointConfig config) {
  160.         try {
  161.             if (StringUtils.isBlank(userId) || "undefined".equals(userId)) {
  162.                 sendError(userId, "参数有误");
  163.                 return;
  164.             }
  165.             HttpSession httpSession = (HttpSession) config.getUserProperties().get(HttpSession.class.getName());
  166.             User user = (User) httpSession.getAttribute(USER_LOGIN_STATE);
  167.             if (user != null) {
  168.                 this.session = session;
  169.                 this.httpSession = httpSession;
  170.             }
  171.             if (!"NaN".equals(teamId)) {
  172.                 if (!ROOMS.containsKey(teamId)) {
  173.                     ConcurrentHashMap<String, WebSocket> room = new ConcurrentHashMap<>(0);
  174.                     room.put(userId, this);
  175.                     ROOMS.put(String.valueOf(teamId), room);
  176.                     // 在线数加1
  177.                     addOnlineCount();
  178.                 } else {
  179.                     if (!ROOMS.get(teamId).containsKey(userId)) {
  180.                         ROOMS.get(teamId).put(userId, this);
  181.                         // 在线数加1
  182.                         addOnlineCount();
  183.                     }
  184.                 }
  185.             } else {
  186.                 SESSIONS.add(session);
  187.                 SESSION_POOL.put(userId, session);
  188.                 sendAllUsers();
  189.             }
  190.         } catch (Exception e) {
  191.             e.printStackTrace();
  192.         }
  193.     }
  194.     /**
  195.      * 关闭
  196.      *
  197.      * @param userId  用户id
  198.      * @param teamId  团队id
  199.      * @param session 会话
  200.      */
  201.     @OnClose
  202.     public void onClose(@PathParam("userId") String userId, @PathParam(value = "teamId") String teamId, Session session) {
  203.         try {
  204.             if (!"NaN".equals(teamId)) {
  205.                 ROOMS.get(teamId).remove(userId);
  206.                 if (getOnlineCount() > 0) {
  207.                     subOnlineCount();
  208.                 }
  209.             } else {
  210.                 if (!SESSION_POOL.isEmpty()) {
  211.                     SESSION_POOL.remove(userId);
  212.                     SESSIONS.remove(session);
  213.                 }
  214.                 sendAllUsers();
  215.             }
  216.         } catch (Exception e) {
  217.             e.printStackTrace();
  218.         }
  219.     }
  220.     /**
  221.      * 消息
  222.      *
  223.      * @param message 消息
  224.      * @param userId  用户id
  225.      */
  226.     @OnMessage
  227.     public void onMessage(String message, @PathParam("userId") String userId) {
  228.         if ("PING".equals(message)) {
  229.             sendOneMessage(userId, "pong");
  230.             return;
  231.         }
  232.         MessageRequest messageRequest = new Gson().fromJson(message, MessageRequest.class);
  233.         Long toId = messageRequest.getToId();
  234.         Long teamId = messageRequest.getTeamId();
  235.         String text = messageRequest.getText();
  236.         Integer chatType = messageRequest.getChatType();
  237.         User fromUser = userService.getById(userId);
  238.         Team team = teamService.getById(teamId);
  239.         if (chatType == PRIVATE_CHAT) {
  240.             // 私聊
  241.             privateChat(fromUser, toId, text, chatType);
  242.         } else if (chatType == TEAM_CHAT) {
  243.             // 队伍内聊天
  244.             teamChat(fromUser, text, team, chatType);
  245.         } else {
  246.             // 群聊
  247.             hallChat(fromUser, text, chatType);
  248.         }
  249.     }
  250.     /**
  251.      * 队伍聊天
  252.      *
  253.      * @param user     用户
  254.      * @param text     文本
  255.      * @param team     团队
  256.      * @param chatType 聊天类型
  257.      */
  258.     private void teamChat(User user, String text, Team team, Integer chatType) {
  259.         ChatMessageVO ChatMessageVO = new ChatMessageVO();
  260.         WebSocketVO fromWebSocketVO = new WebSocketVO();
  261.         BeanUtils.copyProperties(user, fromWebSocketVO);
  262.         ChatMessageVO.setFormUser(fromWebSocketVO);
  263.         ChatMessageVO.setText(text);
  264.         ChatMessageVO.setTeamId(team.getId());
  265.         ChatMessageVO.setChatType(chatType);
  266.         ChatMessageVO.setCreateTime(DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
  267.         if (user.getId() == team.getUserId() || user.getRole() == ADMIN_ROLE) {
  268.             ChatMessageVO.setIsAdmin(true);
  269.         }
  270.         User loginUser = (User) this.httpSession.getAttribute(USER_LOGIN_STATE);
  271.         if (loginUser.getId() == user.getId()) {
  272.             ChatMessageVO.setIsMy(true);
  273.         }
  274.         String toJson = new Gson().toJson(ChatMessageVO);
  275.         try {
  276.             broadcast(String.valueOf(team.getId()), toJson);
  277.             saveChat(user.getId(), null, text, team.getId(), chatType);
  278.             chatService.deleteKey(CACHE_CHAT_TEAM, String.valueOf(team.getId()));
  279.         } catch (Exception e) {
  280.             throw new RuntimeException(e);
  281.         }
  282.     }
  283.     /**
  284.      * 大厅聊天
  285.      *
  286.      * @param user     用户
  287.      * @param text     文本
  288.      * @param chatType 聊天类型
  289.      */
  290.     private void hallChat(User user, String text, Integer chatType) {
  291.         ChatMessageVO ChatMessageVO = new ChatMessageVO();
  292.         WebSocketVO fromWebSocketVO = new WebSocketVO();
  293.         BeanUtils.copyProperties(user, fromWebSocketVO);
  294.         ChatMessageVO.setFormUser(fromWebSocketVO);
  295.         ChatMessageVO.setText(text);
  296.         ChatMessageVO.setChatType(chatType);
  297.         ChatMessageVO.setCreateTime(DateUtil.format(new Date(), "yyyy年MM月dd日 HH:mm:ss"));
  298.         if (user.getRole() == ADMIN_ROLE) {
  299.             ChatMessageVO.setIsAdmin(true);
  300.         }
  301.         User loginUser = (User) this.httpSession.getAttribute(USER_LOGIN_STATE);
  302.         if (loginUser.getId() == user.getId()) {
  303.             ChatMessageVO.setIsMy(true);
  304.         }
  305.         String toJson = new Gson().toJson(ChatMessageVO);
  306.         sendAllMessage(toJson);
  307.         saveChat(user.getId(), null, text, null, chatType);
  308.         chatService.deleteKey(CACHE_CHAT_HALL, String.valueOf(user.getId()));
  309.     }
  310.     /**
  311.      * 私聊
  312.      *
  313.      * @param user     用户
  314.      * @param toId     为id
  315.      * @param text     文本
  316.      * @param chatType 聊天类型
  317.      */
  318.     private void privateChat(User user, Long toId, String text, Integer chatType) {
  319.         ChatMessageVO ChatMessageVO = chatService.chatResult(user.getId(), toId, text, chatType, DateUtil.date(System.currentTimeMillis()));
  320.         User loginUser = (User) this.httpSession.getAttribute(USER_LOGIN_STATE);
  321.         if (loginUser.getId() == user.getId()) {
  322.             ChatMessageVO.setIsMy(true);
  323.         }
  324.         String toJson = new Gson().toJson(ChatMessageVO);
  325.         sendOneMessage(toId.toString(), toJson);
  326.         saveChat(user.getId(), toId, text, null, chatType);
  327.         chatService.deleteKey(CACHE_CHAT_PRIVATE, user.getId() + "" + toId);
  328.         chatService.deleteKey(CACHE_CHAT_PRIVATE, toId + "" + user.getId());
  329.     }
  330.     /**
  331.      * 保存聊天
  332.      *
  333.      * @param userId   用户id
  334.      * @param toId     为id
  335.      * @param text     文本
  336.      * @param teamId   团队id
  337.      * @param chatType 聊天类型
  338.      */
  339.     private void saveChat(Long userId, Long toId, String text, Long teamId, Integer chatType) {
  340. //        if (chatType == PRIVATE_CHAT) {
  341. //            User user = userService.getById(userId);
  342. //            Set<Long> userIds = stringJsonListToLongSet(user.getFriendIds());
  343. //            if (!userIds.contains(toId)) {
  344. //                sendError(String.valueOf(userId), "该用户不是你的好友");
  345. //                return;
  346. //            }
  347. //        }
  348.         Chat chat = new Chat();
  349.         chat.setFromId(userId);
  350.         chat.setText(String.valueOf(text));
  351.         chat.setChatType(chatType);
  352.         chat.setCreateTime(new Date());
  353.         if (toId != null && toId > 0) {
  354.             chat.setToId(toId);
  355.         }
  356.         if (teamId != null && teamId > 0) {
  357.             chat.setTeamId(teamId);
  358.         }
  359.         chatService.save(chat);
  360.     }
  361.     /**
  362.      * 发送失败
  363.      *
  364.      * @param userId       用户id
  365.      * @param errorMessage 错误消息
  366.      */
  367.     private void sendError(String userId, String errorMessage) {
  368.         JSONObject obj = new JSONObject();
  369.         obj.set("error", errorMessage);
  370.         sendOneMessage(userId, obj.toString());
  371.     }
  372.     /**
  373.      * 广播消息
  374.      *
  375.      * @param message 消息
  376.      */
  377.     public void sendAllMessage(String message) {
  378.         for (Session session : SESSIONS) {
  379.             try {
  380.                 if (session.isOpen()) {
  381.                     synchronized (session) {
  382.                         session.getBasicRemote().sendText(message);
  383.                     }
  384.                 }
  385.             } catch (Exception e) {
  386.                 e.printStackTrace();
  387.             }
  388.         }
  389.     }
  390.     /**
  391.      * 发送一个消息
  392.      *
  393.      * @param userId  用户编号
  394.      * @param message 消息
  395.      */
  396.     public void sendOneMessage(String userId, String message) {
  397.         Session session = SESSION_POOL.get(userId);
  398.         if (session != null && session.isOpen()) {
  399.             try {
  400.                 synchronized (session) {
  401.                     session.getBasicRemote().sendText(message);
  402.                 }
  403.             } catch (Exception e) {
  404.                 e.printStackTrace();
  405.             }
  406.         }
  407.     }
  408.     /**
  409.      * 给所有用户
  410.      */
  411.     public void sendAllUsers() {
  412.         HashMap<String, List<WebSocketVO>> stringListHashMap = new HashMap<>(0);
  413.         List<WebSocketVO> WebSocketVOs = new ArrayList<>();
  414.         stringListHashMap.put("users", WebSocketVOs);
  415.         for (Serializable key : SESSION_POOL.keySet()) {
  416.             User user = userService.getById(key);
  417.             WebSocketVO WebSocketVO = new WebSocketVO();
  418.             BeanUtils.copyProperties(user, WebSocketVO);
  419.             WebSocketVOs.add(WebSocketVO);
  420.         }
  421.         sendAllMessage(JSONUtil.toJsonStr(stringListHashMap));
  422.     }
  423. }
复制代码
这是自己的代码
  1. package com.ruoyi.webSocket;
  2. import com.alibaba.fastjson.JSONObject;
  3. import com.ruoyi.common.utils.StringUtils;
  4. import com.ruoyi.room.domain.Room;
  5. import com.ruoyi.room.service.IRoomService;
  6. import org.slf4j.Logger;
  7. import org.slf4j.LoggerFactory;
  8. import org.springframework.beans.BeansException;
  9. import org.springframework.beans.factory.annotation.Autowired;
  10. import org.springframework.context.ApplicationContext;
  11. import org.springframework.context.ApplicationContextAware;
  12. import org.springframework.stereotype.Component;
  13. import javax.websocket.*;
  14. import javax.websocket.server.PathParam;
  15. import javax.websocket.server.ServerEndpoint;
  16. import java.io.IOException;
  17. import java.util.HashMap;
  18. import java.util.List;
  19. import java.util.Map;
  20. import java.util.concurrent.ConcurrentHashMap;
  21. import java.util.concurrent.CopyOnWriteArrayList;
  22. import java.util.concurrent.atomic.AtomicInteger;
  23. @Component
  24. @ServerEndpoint("/module/websocket/{userId}/{roomId}")
  25. public class WebSocketServer implements ApplicationContextAware {
  26.     private static IRoomService roomService;
  27.     private static final Logger log = LoggerFactory.getLogger(WebSocketServer.class);
  28.     // 保存队伍的连接信息 - 新增
  29.     private static final Map<String, ConcurrentHashMap<String, WebSocketServer>> ROOMS = new HashMap<>();
  30.     //静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
  31.     private static AtomicInteger onlineNum = new AtomicInteger();
  32.     //concurrent包的线程安全Set,用来存放每个客户端对应的WebSocketServer对象。
  33.     private static ConcurrentHashMap<String, Session> sessionPools = new ConcurrentHashMap<>();
  34.     // 线程安全list,用来存放 在线客户端账号
  35.     public static List<String> userList = new CopyOnWriteArrayList<>();
  36.     // 连接成功
  37.     @OnOpen
  38.     public void onOpen(Session session, @PathParam(value = "userId") String userId, @PathParam(value = "roomId") String roomId) {
  39.         // 创建session给客户
  40.         sessionPools.put(userId, session);
  41.         if (!userList.contains(userId)) {
  42.             addOnlineCount();
  43.             userList.add(userId);
  44.         }
  45.         try {
  46.             if (StringUtils.isBlank(userId) || "undefined".equals(userId) ||
  47.                     StringUtils.isBlank(roomId) || "undefined".equals(roomId)) {
  48.                 sendError(userId, "参数有误");
  49.                 return;
  50.             }
  51.             if (!ROOMS.containsKey(roomId)) {
  52.                 // 房间不存在 创建房间
  53.                 ConcurrentHashMap<String, WebSocketServer> room = new ConcurrentHashMap<>(0);
  54.                 room.put(userId, this);
  55.                 ROOMS.put(String.valueOf(roomId), room);
  56.             } else {
  57.                 if (!ROOMS.get(roomId).containsKey(userId)) {
  58.                     // 房间存在 客户不存在 房间加入客户
  59.                     ROOMS.get(roomId).put(userId, this);
  60.                 }
  61.             }
  62.             log.debug("ID为【" + userId + "】的用户加入websocket!当前在线人数为:" + onlineNum);
  63.             log.debug("当前在线:" + userList);
  64.         } catch (Exception e) {
  65.             e.printStackTrace();
  66.         }
  67.     }
  68.     /**
  69.      * 关闭连接
  70.      * @param userId
  71.      */
  72.     @OnClose
  73.     public void onClose(@PathParam(value = "userId") String userId) {
  74.         sessionPools.remove(userId);
  75.         if (userList.contains(userId)) {
  76.             userList.remove(userId);
  77.             subOnlineCount();
  78.         }
  79.         log.debug(userId + "断开webSocket连接!当前人数为" + onlineNum);
  80.     }
  81.     /**
  82.      * 消息监听 接收客户端消息
  83.      * @param message
  84.      * @throws IOException
  85.      */
  86.     @OnMessage
  87.     public void onMessage(String message) throws IOException {
  88.         JSONObject jsonObject = JSONObject.parseObject(message);
  89.         String userId = jsonObject.getString("userId");
  90.         String roomId = jsonObject.getString("roomId");
  91.         String type = jsonObject.getString("type");
  92.         if (type.equals(MessageType.DETAIL.getType())) {
  93.             log.debug("房间详情");
  94.             try {
  95.                 Room room = roomService.selectRoomById(Long.parseLong(roomId));
  96.                 jsonObject.put("roomInfo", room);
  97.                 ConcurrentHashMap<String, WebSocketServer> map = ROOMS.get(roomId);
  98.                 // 获取玩家列表 keySet获取map集合key的集合  然后在遍历key即可
  99.                 for (String key : map.keySet()) {
  100.                     try {
  101.                         sendToUser(key, JSONObject.toJSONString(jsonObject));
  102.                     } catch (Exception e) {
  103.                         e.printStackTrace();
  104.                     }
  105.                 }
  106.             } catch (NumberFormatException e) {
  107.                 System.out.println("转换错误: " + e.getMessage());
  108.             }
  109.         }
  110.     }
  111.     /**
  112.      * 连接错误
  113.      * @param session
  114.      * @param throwable
  115.      * @throws IOException
  116.      */
  117.     @OnError
  118.     public void onError(Session session, Throwable throwable) throws IOException {
  119.         log.error("websocket连接错误!");
  120.         throwable.printStackTrace();
  121.     }
  122.     /**
  123.      * 发送消息
  124.      */
  125.     public void sendMessage(Session session, String message) throws IOException, EncodeException {
  126.         if (session != null) {
  127.             synchronized (session) {
  128.                 session.getBasicRemote().sendText(message);
  129.             }
  130.         }
  131.     }
  132.     /**
  133.      * 给指定用户发送信息
  134.      */
  135.     public void sendToUser(String userId, String message) {
  136.         Session session = sessionPools.get(userId);
  137.         try {
  138.             if (session != null) {
  139.                 sendMessage(session, message);
  140.             }else {
  141.                 log.debug("推送用户不在线");
  142.             }
  143.         } catch (Exception e) {
  144.             e.printStackTrace();
  145.         }
  146.     }
  147.     public static void addOnlineCount() {
  148.         onlineNum.incrementAndGet();
  149.     }
  150.     public static void subOnlineCount() {
  151.         onlineNum.decrementAndGet();
  152.     }
  153.     /**
  154.      * 发送失败
  155.      *
  156.      * @param userId       用户id
  157.      * @param errorMessage 错误消息
  158.      */
  159.     private void sendError(String userId, String errorMessage) {
  160.         JSONObject obj = new JSONObject();
  161.         obj.put("error", errorMessage);
  162.         sendOneMessage(userId, obj.toString());
  163.     }
  164.     /**
  165.      * 发送一个消息
  166.      *
  167.      * @param userId  用户编号
  168.      * @param message 消息
  169.      */
  170.     public void sendOneMessage(String userId, String message) {
  171.         Session session = sessionPools.get(userId);
  172.         if (session != null && session.isOpen()) {
  173.             try {
  174.                 synchronized (session) {
  175.                     session.getBasicRemote().sendText(message);
  176.                 }
  177.             } catch (Exception e) {
  178.                 e.printStackTrace();
  179.             }
  180.         }
  181.     }
  182. }
复制代码
修改后的代码
  1. package com.ruoyi.webSocket;
  2. import com.alibaba.fastjson.JSONObject;
  3. import com.ruoyi.common.utils.StringUtils;
  4. import com.ruoyi.room.domain.Room;
  5. import com.ruoyi.room.service.IRoomService;
  6. import org.slf4j.Logger;
  7. import org.slf4j.LoggerFactory;
  8. import org.springframework.beans.BeansException;
  9. import org.springframework.beans.factory.annotation.Autowired;
  10. import org.springframework.context.ApplicationContext;
  11. import org.springframework.context.ApplicationContextAware;
  12. import org.springframework.stereotype.Component;
  13. import javax.websocket.*;
  14. import javax.websocket.server.PathParam;
  15. import javax.websocket.server.ServerEndpoint;
  16. import java.io.IOException;
  17. import java.util.HashMap;
  18. import java.util.List;
  19. import java.util.Map;
  20. import java.util.concurrent.ConcurrentHashMap;
  21. import java.util.concurrent.CopyOnWriteArrayList;
  22. import java.util.concurrent.atomic.AtomicInteger;
  23. @Component
  24. @ServerEndpoint("/module/websocket/{userId}/{roomId}")
  25. public class WebSocketServer implements ApplicationContextAware {
  26.     private static ApplicationContext context;
  27.     @Override
  28.     public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
  29.         context = applicationContext;
  30.     }
  31.     public static <roomService> roomService getBean(Class<roomService> beanClass) {
  32.         return context.getBean(beanClass);
  33.     }
  34.    
  35.     private static final Logger log = LoggerFactory.getLogger(WebSocketServer.class);
  36.     // 保存队伍的连接信息 - 新增
  37.     private static final Map<String, ConcurrentHashMap<String, WebSocketServer>> ROOMS = new HashMap<>();
  38.     //静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
  39.     private static AtomicInteger onlineNum = new AtomicInteger();
  40.     //concurrent包的线程安全Set,用来存放每个客户端对应的WebSocketServer对象。
  41.     private static ConcurrentHashMap<String, Session> sessionPools = new ConcurrentHashMap<>();
  42.     // 线程安全list,用来存放 在线客户端账号
  43.     public static List<String> userList = new CopyOnWriteArrayList<>();
  44.     // 连接成功
  45.     @OnOpen
  46.     public void onOpen(Session session, @PathParam(value = "userId") String userId, @PathParam(value = "roomId") String roomId) {
  47.         // 创建session给客户
  48.         sessionPools.put(userId, session);
  49.         if (!userList.contains(userId)) {
  50.             addOnlineCount();
  51.             userList.add(userId);
  52.         }
  53.         try {
  54.             if (StringUtils.isBlank(userId) || "undefined".equals(userId) ||
  55.                     StringUtils.isBlank(roomId) || "undefined".equals(roomId)) {
  56.                 sendError(userId, "参数有误");
  57.                 return;
  58.             }
  59.             if (!ROOMS.containsKey(roomId)) {
  60.                 // 房间不存在 创建房间
  61.                 ConcurrentHashMap<String, WebSocketServer> room = new ConcurrentHashMap<>(0);
  62.                 room.put(userId, this);
  63.                 ROOMS.put(String.valueOf(roomId), room);
  64.             } else {
  65.                 if (!ROOMS.get(roomId).containsKey(userId)) {
  66.                     // 房间存在 客户不存在 房间加入客户
  67.                     ROOMS.get(roomId).put(userId, this);
  68.                 }
  69.             }
  70.             log.debug("ID为【" + userId + "】的用户加入websocket!当前在线人数为:" + onlineNum);
  71.             log.debug("当前在线:" + userList);
  72.         } catch (Exception e) {
  73.             e.printStackTrace();
  74.         }
  75.     }
  76.     /**
  77.      * 关闭连接
  78.      * @param userId
  79.      */
  80.     @OnClose
  81.     public void onClose(@PathParam(value = "userId") String userId) {
  82.         sessionPools.remove(userId);
  83.         if (userList.contains(userId)) {
  84.             userList.remove(userId);
  85.             subOnlineCount();
  86.         }
  87.         log.debug(userId + "断开webSocket连接!当前人数为" + onlineNum);
  88.     }
  89.     /**
  90.      * 消息监听 接收客户端消息
  91.      * @param message
  92.      * @throws IOException
  93.      */
  94.     @OnMessage
  95.     public void onMessage(String message) throws IOException {
  96.         JSONObject jsonObject = JSONObject.parseObject(message);
  97.         String userId = jsonObject.getString("userId");
  98.         String roomId = jsonObject.getString("roomId");
  99.         String type = jsonObject.getString("type");
  100.         if (type.equals(MessageType.DETAIL.getType())) {
  101.             log.debug("房间详情");
  102.             try {
  103.                 Room room = context.getBean(IRoomService.class).selectRoomById(Long.parseLong(roomId));
  104.                 jsonObject.put("roomInfo", room);
  105.                 ConcurrentHashMap<String, WebSocketServer> map = ROOMS.get(roomId);
  106.                 // 获取玩家列表 keySet获取map集合key的集合  然后在遍历key即可
  107.                 for (String key : map.keySet()) {
  108.                     try {
  109.                         sendToUser(key, JSONObject.toJSONString(jsonObject));
  110.                     } catch (Exception e) {
  111.                         e.printStackTrace();
  112.                     }
  113.                 }
  114.             } catch (NumberFormatException e) {
  115.                 System.out.println("转换错误: " + e.getMessage());
  116.             }
  117.         }
  118.     }
  119.     /**
  120.      * 连接错误
  121.      * @param session
  122.      * @param throwable
  123.      * @throws IOException
  124.      */
  125.     @OnError
  126.     public void onError(Session session, Throwable throwable) throws IOException {
  127.         log.error("websocket连接错误!");
  128.         throwable.printStackTrace();
  129.     }
  130.     /**
  131.      * 发送消息
  132.      */
  133.     public void sendMessage(Session session, String message) throws IOException, EncodeException {
  134.         if (session != null) {
  135.             synchronized (session) {
  136.                 session.getBasicRemote().sendText(message);
  137.             }
  138.         }
  139.     }
  140.     /**
  141.      * 给指定用户发送信息
  142.      */
  143.     public void sendToUser(String userId, String message) {
  144.         Session session = sessionPools.get(userId);
  145.         try {
  146.             if (session != null) {
  147.                 sendMessage(session, message);
  148.             }else {
  149.                 log.debug("推送用户不在线");
  150.             }
  151.         } catch (Exception e) {
  152.             e.printStackTrace();
  153.         }
  154.     }
  155.     public static void addOnlineCount() {
  156.         onlineNum.incrementAndGet();
  157.     }
  158.     public static void subOnlineCount() {
  159.         onlineNum.decrementAndGet();
  160.     }
  161.     /**
  162.      * 发送失败
  163.      *
  164.      * @param userId       用户id
  165.      * @param errorMessage 错误消息
  166.      */
  167.     private void sendError(String userId, String errorMessage) {
  168.         JSONObject obj = new JSONObject();
  169.         obj.put("error", errorMessage);
  170.         sendOneMessage(userId, obj.toString());
  171.     }
  172.     /**
  173.      * 发送一个消息
  174.      *
  175.      * @param userId  用户编号
  176.      * @param message 消息
  177.      */
  178.     public void sendOneMessage(String userId, String message) {
  179.         Session session = sessionPools.get(userId);
  180.         if (session != null && session.isOpen()) {
  181.             try {
  182.                 synchronized (session) {
  183.                     session.getBasicRemote().sendText(message);
  184.                 }
  185.             } catch (Exception e) {
  186.                 e.printStackTrace();
  187.             }
  188.         }
  189.     }
  190. }
复制代码
焦点代码
  1. private static ApplicationContext context;
  2.     @Override
  3.     public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
  4.         context = applicationContext;
  5.     }
  6.     public static <roomService> roomService getBean(Class<roomService> beanClass) {
  7.         return context.getBean(beanClass);
  8.     }
复制代码
  1.                 Room room = context.getBean(IRoomService.class).selectRoomById(Long.parseLong(roomId));
复制代码
原因:执行的先后顺序吧,详细还没仔细相识

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

卖不甜枣

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表