tangbin il y a 10 mois
Parent
commit
9d93ca2d96

+ 80 - 11
yezhu-api/src/main/java/com/kioor/websocket/WebSocketServer.java

@@ -10,12 +10,19 @@ package com.kioor.websocket;
 
 import com.kioor.common.exception.ErrorCode;
 import com.kioor.common.exception.RenException;
+import com.kioor.common.redis.RedisKeys;
+import com.kioor.common.redis.RedisUtils;
 import com.kioor.common.utils.JsonUtils;
+import com.kioor.room.dto.RoomDTO;
+import com.kioor.room.service.UserHousingEstateService;
 import com.kioor.user.entity.TokenEntity;
+import com.kioor.user.entity.UserEntity;
 import com.kioor.user.service.TokenService;
+import com.kioor.user.service.UserService;
 import com.kioor.websocket.config.WebSocketConfig;
 import com.kioor.websocket.data.MessageData;
 import com.kioor.websocket.data.WebSocketData;
+import com.kioor.websocket.dto.MsgWebSocket;
 import jakarta.websocket.*;
 import jakarta.websocket.server.PathParam;
 import jakarta.websocket.server.ServerEndpoint;
@@ -62,19 +69,62 @@ public class WebSocketServer {
         if (tokenEntity == null || tokenEntity.getExpireDate().getTime() < System.currentTimeMillis()) {
             throw new RenException(ErrorCode.TOKEN_INVALID);
         }
-        if(clients.containsKey(tokenEntity.getUserId())){
-            servers.remove(clients.get(tokenEntity.getUserId()).getId());
-            clients.remove(tokenEntity.getUserId());
-        }
+        //先判断是否在线,如果在线踢下线
+        kickUserOffline(tokenEntity.getUserId());
+
+        //在线初始化
         servers.put(session.getId(), new WebSocketData(tokenEntity.getUserId(), session));
         clients.put(tokenEntity.getUserId(), session);
+        //通过用户id查询小区id
+        UserHousingEstateService userHousingEstateService = applicationContext.getBean(UserHousingEstateService.class);
+        List<RoomDTO> roomList = userHousingEstateService.getRoomsByUserId(tokenEntity.getUserId());
+        //加入小区群聊
+        RedisUtils redisUtils = applicationContext.getBean(RedisUtils.class);
+        UserService userService =  applicationContext.getBean(UserService.class);
+        UserEntity userEntity = userService.getUserByUserId(tokenEntity.getUserId());
+        //登录用户放入小区在线列表中
+        roomList.forEach(room -> {
+            redisUtils.hSet(RedisKeys.getSocketGroupUserKey()+room.getHousingEstateId(),tokenEntity.getUserId().toString(),userEntity);
+        });
+
+
     }
 
     @OnClose
     public void onClose(Session session) {
         //客户端断开连接
-        servers.remove(session.getId());
         log.debug("websocket close, session id:" + session.getId());
+        Long userId = servers.get(session.getId()).getUserId();
+        //踢下线
+        kickUserOffline(userId);
+
+        //通过用户id查询小区id
+        UserHousingEstateService userHousingEstateService = applicationContext.getBean(UserHousingEstateService.class);
+        List<RoomDTO> roomList = userHousingEstateService.getRoomsByUserId(userId);
+
+        RedisUtils redisUtils = applicationContext.getBean(RedisUtils.class);
+
+        //从redis的小区群聊中删除用户
+        roomList.forEach(room -> {
+            redisUtils.hDel(RedisKeys.getSocketGroupUserKey()+room.getHousingEstateId(),userId.toString());
+        });
+    }
+    //踢下线
+    private void kickUserOffline(Long userId) {
+        if(clients.containsKey(userId)){
+            Session session = clients.get(userId);
+            if (session != null && session.isOpen()) {
+                try {
+                    session.close();
+                } catch (IOException e) {
+                    // Handle exception
+                } finally {
+                    servers.remove(clients.get(userId).getId());
+                    clients.remove(userId);
+                }
+            }
+        }
+
     }
 
     @OnError
@@ -86,12 +136,31 @@ public class WebSocketServer {
     @OnMessage
     public void onMessage(Session session, String msg) {
         log.info("session id: " + session.getId() + ", message:" + msg);
-
-        MessageData<String> message = new MessageData<String>().msg("你说啥子");
-//        List<Long> userIdList = new ArrayList<>();
-//        userIdList.add(1806260428364058625L);
-//        sendMessage(userIdList, message);
-        sendMessage(1806260428364058625L, message);
+        RedisUtils redisUtils = applicationContext.getBean(RedisUtils.class);
+        //msg Json字符串转为MsgWebSocket对象
+        MsgWebSocket fromMsgDetail = JsonUtils.parseObject(msg, MsgWebSocket.class);
+        if (fromMsgDetail != null && fromMsgDetail.getToId() != null) {
+
+            MessageData<String> message = new MessageData<String>().msg(msg);
+            switch(fromMsgDetail.getToType()){
+                case 1:
+                    //发送给指定用户
+                    sendMessage(fromMsgDetail.getToId(), message);
+                    break;
+                case 2:
+                    //发送给小区业主群
+                    //从redis通过小区id查找小区用户id
+                    Map<String,Object> userList =redisUtils.hGetAll(RedisKeys.getSocketGroupUserKey()+fromMsgDetail.getToId());
+                    if(userList!=null && !userList.isEmpty()){
+                        //将userList的key取出来转成Long放入userIdList
+                        List<Long> userIdList = userList.keySet().stream().map(Long::parseLong).toList();
+                        sendMessage(userIdList, message);
+                    }
+                    break;
+                default:
+                    break;
+            }
+        }
     }
 
     /**

+ 49 - 0
yezhu-api/src/main/java/com/kioor/websocket/dto/MsgWebSocket.java

@@ -0,0 +1,49 @@
+package com.kioor.websocket.dto;
+
+import lombok.Data;
+
+/**
+ * 项目名称: toby-yezhu
+ * 文件名称: UserWebSocket
+ * 描述: socket传递用户信息中间类
+ * <p>
+ * 创建人: 唐斌
+ * 创建时间: 2024/7/5
+ * <p>
+ * 版权所有 © 2024 TANG BIN. All Rights Reserved.
+ */
+@Data
+public class MsgWebSocket {
+    /**
+     * 发送者ID
+     */
+    private Long fromUserId;
+    /**
+     * 发送者名字
+     */
+    private String fromUsername;
+    /**
+     * 群聊ID
+     */
+    private Long fromGroupId;
+    /**
+     * 群聊名字
+     */
+    private String fromGroupName;
+    /**
+     * 房号
+     */
+    private String fromRoomStr;
+    /**
+     * 接收者类型(0-个人,1-小区业主群)
+     */
+    private int toType;
+    /**
+     * 接收者id
+     */
+    private Long toId;
+    /**
+     * 消息内容
+     */
+    private String message;
+}

+ 5 - 1
yezhu-api/src/main/java/com/kioor/websocket/dto/UserWebSocket.java

@@ -15,7 +15,7 @@ import lombok.Data;
 @Data
 public class UserWebSocket {
     /**
-     * 用户ID
+     * 发送者用户ID
      */
     private String id;
     /**
@@ -38,4 +38,8 @@ public class UserWebSocket {
      * 房号
      */
     private String roomStr;
+    /**
+     * 消息内容
+     */
+    private String msg;
 }

+ 7 - 0
yezhu-common/src/main/java/com/kioor/common/redis/RedisKeys.java

@@ -75,4 +75,11 @@ public class RedisKeys {
     public static String getSmsCaptchaKey(){
         return "api:sms:captcha";
     }
+
+    /**
+     * 小区群聊socket在线用户Key+"小区id"
+     */
+    public static String getSocketGroupUserKey(){
+        return "api:socket:group:";
+    }
 }