From f1aeb1eeb794cd920de99501a5dea6b42faa28da Mon Sep 17 00:00:00 2001 From: liu Date: Tue, 19 Dec 2023 13:13:03 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E4=BA=A4websocket=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../constant/UserTokenConstant.java | 2 ++ .../controller/UserController.java | 3 ++- .../controller/WebSocketServer.java | 3 ++- .../usermanage/UserResourceCheck.java | 19 +++++++++++++++---- 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/virtual-patient-common/src/main/java/com/supervision/constant/UserTokenConstant.java b/virtual-patient-common/src/main/java/com/supervision/constant/UserTokenConstant.java index a45b5bd2..34aecbd4 100644 --- a/virtual-patient-common/src/main/java/com/supervision/constant/UserTokenConstant.java +++ b/virtual-patient-common/src/main/java/com/supervision/constant/UserTokenConstant.java @@ -5,4 +5,6 @@ public interface UserTokenConstant { String KICK_CHANNEL = "USER:KICK:CHANNEL"; + Integer KICK_CODE = 10000; + } diff --git a/virtual-patient-web/src/main/java/com/supervision/controller/UserController.java b/virtual-patient-web/src/main/java/com/supervision/controller/UserController.java index 7144af3b..77406317 100644 --- a/virtual-patient-web/src/main/java/com/supervision/controller/UserController.java +++ b/virtual-patient-web/src/main/java/com/supervision/controller/UserController.java @@ -12,6 +12,7 @@ import com.supervision.pojo.vo.UserInfoReqVo; import com.supervision.pojo.vo.UserInfoResVo; import com.supervision.service.UserManageService; import com.supervision.service.UserService; +import com.supervision.usermanage.UserWebSocketDTO; import com.supervision.usermanage.UserResourceCheck; import com.supervision.util.TokenUtil; import com.supervision.util.UserUtil; @@ -63,7 +64,7 @@ public class UserController { @ApiOperation("踢用户下线") @GetMapping("kickUser") public void kickUser(String userId) { - redisTemplate.convertAndSend(UserTokenConstant.KICK_CHANNEL, userId); + redisTemplate.convertAndSend(UserTokenConstant.KICK_CHANNEL, JSONUtil.toJsonStr(new UserWebSocketDTO(userId, null))); } @ApiOperation("查看资源是否有剩余") diff --git a/virtual-patient-web/src/main/java/com/supervision/controller/WebSocketServer.java b/virtual-patient-web/src/main/java/com/supervision/controller/WebSocketServer.java index 8a7e436a..75f90b05 100644 --- a/virtual-patient-web/src/main/java/com/supervision/controller/WebSocketServer.java +++ b/virtual-patient-web/src/main/java/com/supervision/controller/WebSocketServer.java @@ -29,11 +29,12 @@ public class WebSocketServer { private static UserResourceCheck userResourceCheck ; + // 因为是ServerEndpoint是多例,所以需要这样注入 @Autowired public void setUserResourceCheck(UserResourceCheck userResourceCheck) { WebSocketServer.userResourceCheck = userResourceCheck; } - + // 因为是ServerEndpoint是多例,所以需要这样注入 @Autowired public void setRedisTemplate(RedisTemplate redisTemplate) { WebSocketServer.redisTemplate = redisTemplate; diff --git a/virtual-patient-web/src/main/java/com/supervision/usermanage/UserResourceCheck.java b/virtual-patient-web/src/main/java/com/supervision/usermanage/UserResourceCheck.java index dfc1a7c9..b485deaa 100644 --- a/virtual-patient-web/src/main/java/com/supervision/usermanage/UserResourceCheck.java +++ b/virtual-patient-web/src/main/java/com/supervision/usermanage/UserResourceCheck.java @@ -7,6 +7,7 @@ import com.baomidou.lock.annotation.Lock4j; import com.supervision.constant.UserTokenConstant; import com.supervision.controller.WebSocketServer; import com.supervision.exception.BusinessException; +import lombok.Data; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; @@ -43,23 +44,33 @@ public class UserResourceCheck { } log.info("用户:{}开始登录,缓存到Redis,并尝试把该用户已有客户端踢下线", uid); // 链接之前先把之前的用户踢下线(ignoreSessionId防止把当前用户踢下线) - // 注意,这里如果用户没有进到问诊页面,只是在问诊大厅时,是不会被踢掉的.(因为这时没有建立websocket连接) + // 注意,这里如果用户没有进到问诊页面,只是在问诊大厅时,是不会被踢掉的.(因为这时没有建立websocket连接,还没与放到SESSION_POOL里面去) redisTemplate.convertAndSend(UserTokenConstant.KICK_CHANNEL, JSONUtil.toJsonStr(new UserWebSocketDTO(uid, session.getId()))); + log.info("尝试踢该用户{}的其他session下线,忽略sessionId:{}",uid,session.getId()); redisTemplate.opsForHash().put(UserTokenConstant.USER_WEBSOCKET_CACHE, uid, session.getId()); } // 实现一个方法用于踢下线用户,走的是Redis的消息队列 public void kickUser(String userId, String ignoreSessionId) throws IOException { - log.info("尝试主动踢用户:{}下线", userId); + log.info("尝试踢用户:{}下线", userId); Session session = WebSocketServer.SESSION_POOL.get(userId); // 只有不是忽略剔除的sessionId才可以踢下线 if (ObjectUtil.isNotEmpty(session) && !StrUtil.equals(ignoreSessionId, session.getId())) { + session.getBasicRemote().sendText(JSONUtil.toJsonStr(new Kick())); session.close(new CloseReason(CloseReason.CloseCodes.NORMAL_CLOSURE, "用户被踢下线")); WebSocketServer.SESSION_POOL.remove(userId); - log.info("主动踢用户:{},sessionId:{} 下线成功", userId, session.getId()); + log.info("踢用户:{},sessionId:{} 下线成功", userId, session.getId()); return; } - log.info("主动踢用户:{}下线,未找到用户,踢下线失败", userId); + log.info("踢用户:{}下线,未找到用户,踢下线失败", userId); + } + + @Data + public static class Kick { + private final Integer code = UserTokenConstant.KICK_CODE; + + private final String message = "用户被踢下线"; + } }