diff --git a/virtual-patient-common/src/main/java/com/supervision/config/JwtInterceptor.java b/virtual-patient-common/src/main/java/com/supervision/config/JwtInterceptor.java
index 6dfb5735..70fe2534 100644
--- a/virtual-patient-common/src/main/java/com/supervision/config/JwtInterceptor.java
+++ b/virtual-patient-common/src/main/java/com/supervision/config/JwtInterceptor.java
@@ -48,12 +48,9 @@ public class JwtInterceptor implements HandlerInterceptor {
                 throw new BusinessException("当前用户未登录", HttpStatus.UNAUTHORIZED.value());
             }
         }
-
         JWT jwt = JWTUtil.parseToken(token);
         // 校验token是否过期,如果过期了,需要提示过期重新登录
         checkTokenExpire(jwt);
-        // 校验是否重复登录
-        //checkSingleLogin(jwt);
         cacheAuth(jwt);
         return true;
     }
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 edf4a2b3..0b1caaa6 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
@@ -7,6 +7,8 @@ public interface UserTokenConstant {
 
     Integer KICK_CODE = 10000;
 
-    Integer KEEPALIVE_CODE = 10001;
+    Integer NO_RESOURCE_CODE = 10001;
+
+    Integer KEEPALIVE_CODE = 10002;
 
 }
diff --git a/virtual-patient-model/src/main/java/com/supervision/model/DiagnosisAncillaryRecord.java b/virtual-patient-model/src/main/java/com/supervision/model/DiagnosisAncillaryRecord.java
index f4826bfc..6a9db76c 100644
--- a/virtual-patient-model/src/main/java/com/supervision/model/DiagnosisAncillaryRecord.java
+++ b/virtual-patient-model/src/main/java/com/supervision/model/DiagnosisAncillaryRecord.java
@@ -51,12 +51,17 @@ public class DiagnosisAncillaryRecord extends Model<DiagnosisAncillaryRecord> im
     @ApiModelProperty("检查结果")
     private String result;
 
+    @ApiModelProperty("诊断判读结果")
+    private String assessmentResult;
+
     @ApiModelProperty("是否是证实诊断依据(0否1是)")
     private Integer basisConfirmFlag;
 
     @ApiModelProperty("是否是鉴别依据(0否1是)")
     private Integer basisIdentificationFlag;
 
+
+
     /**
      * 创建人ID
      */
diff --git a/virtual-patient-model/src/main/java/com/supervision/vo/ask/AskAncillaryHistoryResVO.java b/virtual-patient-model/src/main/java/com/supervision/vo/ask/AskAncillaryHistoryResVO.java
index 1edddf16..c84a8d42 100644
--- a/virtual-patient-model/src/main/java/com/supervision/vo/ask/AskAncillaryHistoryResVO.java
+++ b/virtual-patient-model/src/main/java/com/supervision/vo/ask/AskAncillaryHistoryResVO.java
@@ -35,6 +35,9 @@ public class AskAncillaryHistoryResVO {
     @ApiModelProperty("是否诊断判读 0不需要 1需要")
     private Integer diagnosisAssessmentFlag;
 
+    @ApiModelProperty("诊断判读结果")
+    private String assessmentResult;
+
     @ApiModelProperty("关联的初步诊断")
     private List<DiagnosisPrimaryVO> primaryList;
 
diff --git a/virtual-patient-model/src/main/resources/mapper/DiagnosisAncillaryRecordMapper.xml b/virtual-patient-model/src/main/resources/mapper/DiagnosisAncillaryRecordMapper.xml
index e9888003..fd671f04 100644
--- a/virtual-patient-model/src/main/resources/mapper/DiagnosisAncillaryRecordMapper.xml
+++ b/virtual-patient-model/src/main/resources/mapper/DiagnosisAncillaryRecordMapper.xml
@@ -10,6 +10,7 @@
         <result property="processId" column="process_id" jdbcType="VARCHAR"/>
         <result property="itemId" column="item_id" jdbcType="VARCHAR"/>
         <result property="result" column="result" jdbcType="VARCHAR"/>
+        <result property="assessmentResult" column="assessment_result" jdbcType="VARCHAR"/>
         <result property="createUserId" column="create_user_id" jdbcType="VARCHAR"/>
         <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
         <result property="updateUserId" column="update_user_id" jdbcType="VARCHAR"/>
@@ -19,7 +20,7 @@
     <sql id="Base_Column_List">
         id
         ,process_id,item_id,primary_id,ancillary_id
-        result,create_user_id,create_time,
+        result,assessment_result,create_user_id,create_time,
         update_user_id,update_time
     </sql>
     <select id="queryAncillaryResultByProcessId"
@@ -42,8 +43,9 @@
         select t2.item_name                 as itemName,
                t2.id                        as itemId,
                t2.type                      as type,
-               t4.primary_id            as primaryId,
+               t4.primary_id                as primaryId,
                t1.result                    as result,
+               t1.assessment_result         as assessmentResult,
                t1.id                        as id,
                t3.diagnosis_assessment_flag as diagnosisAssessmentFlag,
                t1.create_time               as createTime
diff --git a/virtual-patient-web/src/main/java/com/supervision/config/WebSocketConfig.java b/virtual-patient-web/src/main/java/com/supervision/config/WebSocketConfig.java
index e2755bed..b2aab455 100644
--- a/virtual-patient-web/src/main/java/com/supervision/config/WebSocketConfig.java
+++ b/virtual-patient-web/src/main/java/com/supervision/config/WebSocketConfig.java
@@ -25,4 +25,5 @@ public class WebSocketConfig {
         threadPoolTaskScheduler.setRemoveOnCancelPolicy(true);
         return threadPoolTaskScheduler;
     }
+
 }
diff --git a/virtual-patient-web/src/main/java/com/supervision/controller/AskAncillaryController.java b/virtual-patient-web/src/main/java/com/supervision/controller/AskAncillaryController.java
index 34a9a64b..9de3675d 100644
--- a/virtual-patient-web/src/main/java/com/supervision/controller/AskAncillaryController.java
+++ b/virtual-patient-web/src/main/java/com/supervision/controller/AskAncillaryController.java
@@ -2,6 +2,7 @@ package com.supervision.controller;
 
 import com.supervision.model.ConfigAncillaryItem;
 import com.supervision.pojo.vo.AskAncillaryBatchReqVO;
+import com.supervision.pojo.vo.SaveAncillaryAssessmentResultReqVO;
 import com.supervision.vo.ask.AncillaryItemReqVo;
 import com.supervision.vo.ask.AskAncillaryHistoryResVO;
 import com.supervision.pojo.vo.AskAncillaryResultReqVO;
@@ -55,5 +56,11 @@ public class AskAncillaryController {
         return askAncillaryService.queryAskAncillaryHistory(processId);
     }
 
+    @ApiOperation("保存辅助检查判读结果")
+    @GetMapping("saveAncillaryAssessmentResult")
+    public void saveAncillaryAssessmentResult(@RequestBody SaveAncillaryAssessmentResultReqVO reqVO){
+        askAncillaryService.saveAncillaryAssessmentResult(reqVO);
+    }
+
 
 }
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 dcfee9ed..4de37f6c 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
@@ -2,7 +2,9 @@ package com.supervision.controller;
 
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.net.NetUtil;
+import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
+import cn.hutool.json.JSONObjectIter;
 import cn.hutool.json.JSONUtil;
 import com.supervision.constant.UserTokenConstant;
 import com.supervision.exception.BusinessException;
@@ -13,21 +15,23 @@ 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.websocket.dto.UserWebSocketDTO;
+import com.supervision.websocket.UserResourceCheck;
 import com.supervision.util.TokenUtil;
 import com.supervision.util.UserUtil;
+import com.supervision.websocket.dto.WebSocketLoginDTO;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.RequiredArgsConstructor;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.apache.xmlbeans.impl.common.IOUtil;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.data.redis.core.Cursor;
 import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.ScanOptions;
 import org.springframework.web.bind.annotation.*;
 
+import java.io.IOException;
 import java.time.LocalDateTime;
-import java.util.LinkedHashSet;
-import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 
@@ -78,8 +82,32 @@ public class UserController {
 
     @ApiOperation("踢用户下线")
     @GetMapping("kickUser")
-    public void kickUser(String userId) {
-        redisTemplate.convertAndSend(UserTokenConstant.KICK_CHANNEL, JSONUtil.toJsonStr(new UserWebSocketDTO(userId, null)));
+    public void kickUser(String uuid, String userId) throws IOException {
+        if (StrUtil.isNotBlank(uuid)) {
+            redisTemplate.convertAndSend(UserTokenConstant.KICK_CHANNEL, JSONUtil.toJsonStr(new UserWebSocketDTO(uuid)));
+        } else {
+            ScanOptions options = ScanOptions.scanOptions()
+                    .match("*" + userId + "*")     // 可选:使用模式匹配指定要匹配的键
+                    .count(10)                 // 可选:指定每次迭代返回的元素数量
+                    .build();
+
+            Cursor<Map.Entry<Object, Object>> cursor = null;
+            try {
+                cursor = redisTemplate.opsForHash().scan(UserTokenConstant.USER_WEBSOCKET_CACHE, options);
+                while (cursor.hasNext()) {
+                    Map.Entry<Object, Object> entry = cursor.next();
+                    Object value = entry.getValue();
+                    WebSocketLoginDTO bean = JSONUtil.toBean(String.valueOf(value), WebSocketLoginDTO.class);
+                    if (userId.equals(bean.getUserId())) {
+                        redisTemplate.convertAndSend(UserTokenConstant.KICK_CHANNEL, JSONUtil.toJsonStr(new UserWebSocketDTO(bean.getUserId())));
+                    }
+                }
+            } catch (Exception e) {
+                if (ObjectUtil.isNotNull(cursor)) {
+                    cursor.close();
+                }
+            }
+        }
     }
 
     @ApiOperation("查看资源是否有剩余")
@@ -122,7 +150,7 @@ public class UserController {
 
     @ApiOperation("获取当前在线的用户")
     @GetMapping("queryCurrentOnlineUser")
-    public Map<Object, Object> queryCurrentOnlineUser(){
+    public Map<Object, Object> queryCurrentOnlineUser() {
         return redisTemplate.opsForHash().entries(UserTokenConstant.USER_WEBSOCKET_CACHE);
     }
 
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 75f90b05..37d274d0 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
@@ -1,39 +1,33 @@
 package com.supervision.controller;
 
-import cn.hutool.core.util.ObjectUtil;
-import cn.hutool.core.util.StrUtil;
 import com.supervision.constant.UserTokenConstant;
-import com.supervision.usermanage.UserResourceCheck;
-import com.supervision.util.SpringBeanUtil;
+import com.supervision.websocket.UserResourceCheck;
+import com.supervision.websocket.WebSocketSessionPool;
+import com.supervision.websocket.dto.WebSocketLoginDTO;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Component;
 
 import javax.websocket.*;
 import javax.websocket.server.PathParam;
 import javax.websocket.server.ServerEndpoint;
-import java.io.IOException;
-import java.util.concurrent.ConcurrentHashMap;
 
 @Component
 @Slf4j
-@ServerEndpoint("/webSocket/{uid}")
+@ServerEndpoint("/webSocket/{uuid}/{userId}")
 public class WebSocketServer {
 
-    private static RedisTemplate<String, String> redisTemplate ;
+    private static RedisTemplate<String, String> redisTemplate;
 
-    //concurrent包的线程安全Set,用来存放每个客户端对应的WebSocketServer对象。
-    public static final ConcurrentHashMap<String, Session> SESSION_POOL = new ConcurrentHashMap<>();
-
-    private static UserResourceCheck userResourceCheck ;
+    private static UserResourceCheck userResourceCheck;
 
     // 因为是ServerEndpoint是多例,所以需要这样注入
     @Autowired
     public void setUserResourceCheck(UserResourceCheck userResourceCheck) {
         WebSocketServer.userResourceCheck = userResourceCheck;
     }
+
     // 因为是ServerEndpoint是多例,所以需要这样注入
     @Autowired
     public void setRedisTemplate(RedisTemplate<String, String> redisTemplate) {
@@ -44,30 +38,31 @@ public class WebSocketServer {
      * 有客户端连接成功
      */
     @OnOpen
-    public void onOpen(Session session, @PathParam(value = "uid") String uid) {
-        userResourceCheck.achieveDiagnoseResourceAndOpenConnection(uid, session);
-        SESSION_POOL.put(uid, session);
-        log.info("用户:{}登录成功", uid);
+    public void onOpen(Session session, @PathParam(value = "uuid") String uuid, @PathParam(value = "userId") String userId) {
+        // 校验资源数量,并保存
+        userResourceCheck.achieveDiagnoseResourceAndOpenConnection(uuid, userId, session);
+        WebSocketSessionPool.SESSION_POOL.put(uuid, session);
+        log.info("用户:{},UUID:{}登录成功", userId, uuid);
     }
 
     /**
      * 连接关闭调用的方法
      */
     @OnClose
-    public void onClose(Session session, @PathParam(value = "uid") String uid) {
-        redisTemplate.opsForHash().delete(UserTokenConstant.USER_WEBSOCKET_CACHE, uid, session.getId());
-        SESSION_POOL.remove(uid);
-        log.info("用户:{}关闭,从Redis中移除,当前连接数为:{}", uid, redisTemplate.opsForHash().size(UserTokenConstant.USER_WEBSOCKET_CACHE));
+    public void onClose(Session session, @PathParam(value = "uuid") String uuid, @PathParam(value = "userId") String userId) {
+        redisTemplate.opsForHash().delete(UserTokenConstant.USER_WEBSOCKET_CACHE, uuid);
+        WebSocketSessionPool.SESSION_POOL.remove(uuid);
+        log.info("用户:{},uuid:{}关闭,从Redis中移除,当前连接数为:{}", userId, uuid, redisTemplate.opsForHash().size(UserTokenConstant.USER_WEBSOCKET_CACHE));
     }
 
     /**
      * 发生错误
      */
     @OnError
-    public void onError(Session session, @PathParam(value = "uid") String uid, Throwable throwable) {
-        redisTemplate.opsForHash().delete(UserTokenConstant.USER_WEBSOCKET_CACHE, uid, session.getId());
-        SESSION_POOL.remove(uid);
-        log.error("用户:{}发生错误,从Redis中移除,当前连接数为:{}", uid, redisTemplate.opsForHash().size(UserTokenConstant.USER_WEBSOCKET_CACHE), throwable);
+    public void onError(Session session, @PathParam(value = "uuid") String uuid, @PathParam(value = "userId") String userId, Throwable throwable) {
+        redisTemplate.opsForHash().delete(UserTokenConstant.USER_WEBSOCKET_CACHE, uuid);
+        WebSocketSessionPool.SESSION_POOL.remove(uuid);
+        log.error("用户:{},uuid:{}发生错误,从Redis中移除,当前连接数为:{}", userId, uuid, redisTemplate.opsForHash().size(UserTokenConstant.USER_WEBSOCKET_CACHE), throwable);
     }
 
 
diff --git a/virtual-patient-web/src/main/java/com/supervision/pojo/vo/SaveAncillaryAssessmentResultReqVO.java b/virtual-patient-web/src/main/java/com/supervision/pojo/vo/SaveAncillaryAssessmentResultReqVO.java
new file mode 100644
index 00000000..0abc49cf
--- /dev/null
+++ b/virtual-patient-web/src/main/java/com/supervision/pojo/vo/SaveAncillaryAssessmentResultReqVO.java
@@ -0,0 +1,11 @@
+package com.supervision.pojo.vo;
+
+import lombok.Data;
+
+@Data
+public class SaveAncillaryAssessmentResultReqVO {
+
+    private String recordId;
+
+    private String result;
+}
diff --git a/virtual-patient-web/src/main/java/com/supervision/service/AskAncillaryService.java b/virtual-patient-web/src/main/java/com/supervision/service/AskAncillaryService.java
index 6f025e04..fa9cad5c 100644
--- a/virtual-patient-web/src/main/java/com/supervision/service/AskAncillaryService.java
+++ b/virtual-patient-web/src/main/java/com/supervision/service/AskAncillaryService.java
@@ -2,11 +2,13 @@ package com.supervision.service;
 
 import com.supervision.model.ConfigAncillaryItem;
 import com.supervision.pojo.vo.AskAncillaryBatchReqVO;
+import com.supervision.pojo.vo.SaveAncillaryAssessmentResultReqVO;
 import com.supervision.vo.ask.AncillaryItemReqVo;
 import com.supervision.vo.ask.AskAncillaryHistoryResVO;
 import com.supervision.pojo.vo.AskAncillaryResultReqVO;
 import com.supervision.vo.ask.ConfigAncillaryItemResVO;
 import com.supervision.vo.ask.DiagnosisAncillaryRecordVo;
+import org.springframework.web.bind.annotation.RequestBody;
 
 import java.util.List;
 import java.util.Map;
@@ -23,4 +25,6 @@ public interface AskAncillaryService {
     DiagnosisAncillaryRecordVo execAskAncillaryResult(AskAncillaryResultReqVO reqVO);
 
     List<AskAncillaryHistoryResVO> queryAskAncillaryHistory(String processId);
+
+    void saveAncillaryAssessmentResult(SaveAncillaryAssessmentResultReqVO reqVO);
 }
diff --git a/virtual-patient-web/src/main/java/com/supervision/service/impl/AskAncillaryServiceImpl.java b/virtual-patient-web/src/main/java/com/supervision/service/impl/AskAncillaryServiceImpl.java
index 0223a952..ba7caf38 100644
--- a/virtual-patient-web/src/main/java/com/supervision/service/impl/AskAncillaryServiceImpl.java
+++ b/virtual-patient-web/src/main/java/com/supervision/service/impl/AskAncillaryServiceImpl.java
@@ -8,6 +8,7 @@ import com.supervision.exception.BusinessException;
 import com.supervision.model.*;
 import com.supervision.model.Process;
 import com.supervision.pojo.vo.AskAncillaryBatchReqVO;
+import com.supervision.pojo.vo.SaveAncillaryAssessmentResultReqVO;
 import com.supervision.vo.ask.*;
 import com.supervision.pojo.vo.AskAncillaryResultReqVO;
 import com.supervision.service.*;
@@ -148,4 +149,8 @@ public class AskAncillaryServiceImpl implements AskAncillaryService {
         return resList;
     }
 
+    @Override
+    public void saveAncillaryAssessmentResult(SaveAncillaryAssessmentResultReqVO reqVO) {
+
+    }
 }
diff --git a/virtual-patient-web/src/main/java/com/supervision/service/impl/DiagnoseHallServiceImpl.java b/virtual-patient-web/src/main/java/com/supervision/service/impl/DiagnoseHallServiceImpl.java
index fb2b5418..1899b1d7 100644
--- a/virtual-patient-web/src/main/java/com/supervision/service/impl/DiagnoseHallServiceImpl.java
+++ b/virtual-patient-web/src/main/java/com/supervision/service/impl/DiagnoseHallServiceImpl.java
@@ -1,8 +1,6 @@
 package com.supervision.service.impl;
 
-import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.lang.Assert;
-import cn.hutool.core.lang.Opt;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.lock.annotation.Lock4j;
@@ -15,7 +13,7 @@ import com.supervision.vo.ask.DiagnosisPrimaryVO;
 import com.supervision.vo.manage.MedicalRecPageResVO;
 import com.supervision.vo.result.DiagnoseProcessReqVo;
 import com.supervision.vo.result.DiagnoseProcessResVo;
-import com.supervision.usermanage.UserResourceCheck;
+import com.supervision.websocket.UserResourceCheck;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
diff --git a/virtual-patient-web/src/main/java/com/supervision/usermanage/UserWebSocketDTO.java b/virtual-patient-web/src/main/java/com/supervision/usermanage/UserWebSocketDTO.java
deleted file mode 100644
index 063401f1..00000000
--- a/virtual-patient-web/src/main/java/com/supervision/usermanage/UserWebSocketDTO.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.supervision.usermanage;
-
-import lombok.AllArgsConstructor;
-import lombok.Data;
-
-@Data
-@AllArgsConstructor
-public class UserWebSocketDTO {
-
-    private String userId;
-
-    /**
-     * 忽略提除的ID
-     */
-    private String ignoreSessionId;
-
-}
diff --git a/virtual-patient-web/src/main/java/com/supervision/usermanage/KickUserListener.java b/virtual-patient-web/src/main/java/com/supervision/websocket/KickUserListener.java
similarity index 75%
rename from virtual-patient-web/src/main/java/com/supervision/usermanage/KickUserListener.java
rename to virtual-patient-web/src/main/java/com/supervision/websocket/KickUserListener.java
index 3a7a54d9..b24841d1 100644
--- a/virtual-patient-web/src/main/java/com/supervision/usermanage/KickUserListener.java
+++ b/virtual-patient-web/src/main/java/com/supervision/websocket/KickUserListener.java
@@ -1,16 +1,14 @@
-package com.supervision.usermanage;
+package com.supervision.websocket;
 
 import cn.hutool.json.JSONUtil;
 import com.supervision.constant.UserTokenConstant;
-import com.supervision.controller.WebSocketServer;
+import com.supervision.websocket.dto.UserWebSocketDTO;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.redis.connection.Message;
 import org.springframework.data.redis.connection.MessageListener;
 import org.springframework.stereotype.Component;
 
-import java.io.IOException;
-
 
 @Slf4j
 @Component
@@ -23,7 +21,7 @@ public class KickUserListener implements MessageListener {
     public void onMessage(Message message, byte[] pattern) {
         String messageString = message.toString();
         UserWebSocketDTO user = JSONUtil.toBean(messageString, UserWebSocketDTO.class);
-        log.info("Redis的Channel:{}收到踢用户{}下线消息", UserTokenConstant.KICK_CHANNEL, user.getUserId());
-        userResourceCheck.kickUser(user.getUserId(), user.getIgnoreSessionId());
+        log.info("Redis的Channel:{}收到踢用户{}下线消息", UserTokenConstant.KICK_CHANNEL, user.getUuid());
+        userResourceCheck.kickUser(user.getUuid());
     }
 }
diff --git a/virtual-patient-web/src/main/java/com/supervision/usermanage/RedisConfig.java b/virtual-patient-web/src/main/java/com/supervision/websocket/RedisListener.java
similarity index 93%
rename from virtual-patient-web/src/main/java/com/supervision/usermanage/RedisConfig.java
rename to virtual-patient-web/src/main/java/com/supervision/websocket/RedisListener.java
index 68e38764..2cae1e58 100644
--- a/virtual-patient-web/src/main/java/com/supervision/usermanage/RedisConfig.java
+++ b/virtual-patient-web/src/main/java/com/supervision/websocket/RedisListener.java
@@ -1,4 +1,4 @@
-package com.supervision.usermanage;
+package com.supervision.websocket;
 
 import com.supervision.constant.UserTokenConstant;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -9,7 +9,7 @@ import org.springframework.data.redis.listener.ChannelTopic;
 import org.springframework.data.redis.listener.RedisMessageListenerContainer;
 
 @Configuration
-public class RedisConfig {
+public class RedisListener {
 
     @Autowired
     private KickUserListener kickUserListener;
diff --git a/virtual-patient-web/src/main/java/com/supervision/usermanage/UserResourceCheck.java b/virtual-patient-web/src/main/java/com/supervision/websocket/UserResourceCheck.java
similarity index 52%
rename from virtual-patient-web/src/main/java/com/supervision/usermanage/UserResourceCheck.java
rename to virtual-patient-web/src/main/java/com/supervision/websocket/UserResourceCheck.java
index 8584aa62..b1056faa 100644
--- a/virtual-patient-web/src/main/java/com/supervision/usermanage/UserResourceCheck.java
+++ b/virtual-patient-web/src/main/java/com/supervision/websocket/UserResourceCheck.java
@@ -1,12 +1,14 @@
-package com.supervision.usermanage;
+package com.supervision.websocket;
 
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.json.JSONUtil;
 import com.baomidou.lock.annotation.Lock4j;
 import com.supervision.constant.UserTokenConstant;
-import com.supervision.controller.WebSocketServer;
 import com.supervision.exception.BusinessException;
+import com.supervision.websocket.dto.KickDTO;
+import com.supervision.websocket.dto.NoResourceDTO;
+import com.supervision.websocket.dto.WebSocketLoginDTO;
 import lombok.Data;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
@@ -15,12 +17,9 @@ import org.springframework.beans.factory.annotation.Value;
 import javax.websocket.*;
 
 import org.springframework.data.redis.core.RedisTemplate;
-import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
 
 import java.io.IOException;
-import java.util.Map;
-import java.util.Set;
 
 @Slf4j
 @Component
@@ -41,17 +40,17 @@ public class UserResourceCheck {
     }
 
     @Lock4j(name = "achieveDiagnoseResourceAndOpenConnection")
-    public void achieveDiagnoseResourceAndOpenConnection(String uid, Session session) {
+    public void achieveDiagnoseResourceAndOpenConnection(String uuid, String userId, Session session) {
         // 如果小于数字人最大连接数,则可以连接
         if (!achieveDiagnoseResource()) {
+            try {
+                session.getBasicRemote().sendText(JSONUtil.toJsonStr(new NoResourceDTO()));
+            } catch (Exception e) {
+                log.error("发送消息失败", e);
+            }
             throw new BusinessException("暂时没有资源,建立连接失败");
         }
-        log.info("用户:{}开始登录,缓存到Redis,并尝试把该用户已有客户端踢下线", uid);
-        // 链接之前先把之前的用户踢下线(ignoreSessionId防止把当前用户踢下线)
-        // 注意,这里如果用户没有进到问诊页面,只是在问诊大厅时,是不会被踢掉的.(因为这时没有建立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());
+        redisTemplate.opsForHash().put(UserTokenConstant.USER_WEBSOCKET_CACHE, uuid, JSONUtil.toJsonStr(new WebSocketLoginDTO(uuid, userId, session.getId())));
     }
 
     /**
@@ -59,42 +58,27 @@ public class UserResourceCheck {
      */
 
     // 实现一个方法用于踢下线用户,走的是Redis的消息队列
-    public void kickUser(String userId, String ignoreSessionId) {
-        log.info("尝试踢用户:{}下线", userId);
-        Session session = WebSocketServer.SESSION_POOL.get(userId);
+    public void kickUser(String uuid) {
+        log.info("尝试踢uuid:{}下线", uuid);
+        Session session = WebSocketSessionPool.SESSION_POOL.get(uuid);
         // 只有不是忽略剔除的sessionId才可以踢下线
-        if (ObjectUtil.isNotEmpty(session) && !StrUtil.equals(ignoreSessionId, session.getId())) {
+        if (ObjectUtil.isNotEmpty(session)) {
             try {
-                session.getBasicRemote().sendText(JSONUtil.toJsonStr(new Kick()));
+                session.getBasicRemote().sendText(JSONUtil.toJsonStr(new KickDTO()));
                 session.close(new CloseReason(CloseReason.CloseCodes.NORMAL_CLOSURE, "用户被踢下线"));
-                WebSocketServer.SESSION_POOL.remove(userId);
-                log.info("踢用户:{},sessionId:{} 下线成功", userId, session.getId());
+                WebSocketSessionPool.SESSION_POOL.remove(uuid);
+                // 然后从redis中移除掉
+                redisTemplate.opsForHash().delete(UserTokenConstant.USER_WEBSOCKET_CACHE, uuid);
+                log.info("踢UUID:{},sessionId:{} 下线成功", uuid, session.getId());
                 return;
             } catch (IOException e) {
                 log.error("用户:{}的websocket连接异常", e.getMessage());
-                // 连接异常的用户,移除
-                WebSocketServer.SESSION_POOL.remove(userId);
-                // 移除redis中该用户的缓存
-                redisTemplate.opsForHash().delete(UserTokenConstant.USER_WEBSOCKET_CACHE, userId);
+                // TODO 如果用户连接异常,怎么办
+
             }
         }
-        log.info("踢用户:{}下线,未找到用户,踢下线失败", userId);
-    }
-
-    @Data
-    public static class Kick {
-        private final Integer code = UserTokenConstant.KICK_CODE;
-
-        private final String message = "用户被踢下线";
-
+        log.info("踢UUID:{}下线,未找到用户,踢下线失败", uuid);
     }
 
-    @Data
-    public static class Keepalive {
-        private final Integer code = UserTokenConstant.KEEPALIVE_CODE;
-
-        private final String message = "keepalive";
-
-    }
 
 }
diff --git a/virtual-patient-web/src/main/java/com/supervision/websocket/WebSocketSessionPool.java b/virtual-patient-web/src/main/java/com/supervision/websocket/WebSocketSessionPool.java
new file mode 100644
index 00000000..e6d7070c
--- /dev/null
+++ b/virtual-patient-web/src/main/java/com/supervision/websocket/WebSocketSessionPool.java
@@ -0,0 +1,13 @@
+package com.supervision.websocket;
+
+import com.supervision.websocket.dto.WebSocketLoginDTO;
+
+import javax.websocket.Session;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class WebSocketSessionPool {
+
+    //concurrent包的线程安全Set,用来存放每个客户端对应的WebSocketServer对象。
+    public static final ConcurrentHashMap<String, Session> SESSION_POOL = new ConcurrentHashMap<>();
+}
diff --git a/virtual-patient-web/src/main/java/com/supervision/task/WebsocketKeepaliveTask.java b/virtual-patient-web/src/main/java/com/supervision/websocket/WebsocketKeepaliveTask.java
similarity index 53%
rename from virtual-patient-web/src/main/java/com/supervision/task/WebsocketKeepaliveTask.java
rename to virtual-patient-web/src/main/java/com/supervision/websocket/WebsocketKeepaliveTask.java
index c240ddc3..91f6a948 100644
--- a/virtual-patient-web/src/main/java/com/supervision/task/WebsocketKeepaliveTask.java
+++ b/virtual-patient-web/src/main/java/com/supervision/websocket/WebsocketKeepaliveTask.java
@@ -1,13 +1,12 @@
-package com.supervision.task;
+package com.supervision.websocket;
 
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.json.JSONUtil;
-import com.supervision.constant.UserTokenConstant;
-import com.supervision.controller.WebSocketServer;
-import com.supervision.usermanage.UserResourceCheck;
+import com.supervision.websocket.UserResourceCheck;
+import com.supervision.websocket.WebSocketSessionPool;
+import com.supervision.websocket.dto.KeepaliveDTO;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
 
@@ -19,30 +18,20 @@ import java.util.Map;
 @Slf4j
 @RequiredArgsConstructor
 public class WebsocketKeepaliveTask {
-
-    private final RedisTemplate<String, String> redisTemplate;
-
     @Scheduled(fixedDelay = 5 * 1000L)
     public void keepalive() {
-        log.info("websocket保活接口开始,每5秒钟发送一次消息");
-        for (Map.Entry<String, Session> entries : WebSocketServer.SESSION_POOL.entrySet()) {
+        for (Map.Entry<String, Session> entries : WebSocketSessionPool.SESSION_POOL.entrySet()) {
             String userId = entries.getKey();
             Session session = entries.getValue();
             if (ObjectUtil.isNotEmpty(session)) {
                 try {
-
-                    session.getBasicRemote().sendText(JSONUtil.toJsonStr(new UserResourceCheck.Keepalive()));
+                    session.getBasicRemote().sendText(JSONUtil.toJsonStr(new KeepaliveDTO()));
                     log.info("用户:{}的websocket保活成功", userId);
                 } catch (IOException e) {
                     log.error("用户:{}的websocket连接异常", userId, e);
-                    // 连接异常的用户,移除
-                    WebSocketServer.SESSION_POOL.remove(userId);
-                    // 移除redis中该用户的缓存
-                    redisTemplate.opsForHash().delete(UserTokenConstant.USER_WEBSOCKET_CACHE, userId);
                 }
             }
         }
-        log.info("websocket保活接口结束");
     }
 
 }
diff --git a/virtual-patient-web/src/main/java/com/supervision/websocket/dto/KeepaliveDTO.java b/virtual-patient-web/src/main/java/com/supervision/websocket/dto/KeepaliveDTO.java
new file mode 100644
index 00000000..2865c27f
--- /dev/null
+++ b/virtual-patient-web/src/main/java/com/supervision/websocket/dto/KeepaliveDTO.java
@@ -0,0 +1,12 @@
+package com.supervision.websocket.dto;
+
+import com.supervision.constant.UserTokenConstant;
+import lombok.Data;
+
+@Data
+public class KeepaliveDTO {
+
+    private final Integer code = UserTokenConstant.KEEPALIVE_CODE;
+
+    private final String message = "keepalive";
+}
diff --git a/virtual-patient-web/src/main/java/com/supervision/websocket/dto/KickDTO.java b/virtual-patient-web/src/main/java/com/supervision/websocket/dto/KickDTO.java
new file mode 100644
index 00000000..6987fdcc
--- /dev/null
+++ b/virtual-patient-web/src/main/java/com/supervision/websocket/dto/KickDTO.java
@@ -0,0 +1,12 @@
+package com.supervision.websocket.dto;
+
+import com.supervision.constant.UserTokenConstant;
+import lombok.Data;
+
+@Data
+public class KickDTO {
+
+    private final Integer code = UserTokenConstant.KICK_CODE;
+
+    private final String message = "用户被踢下线";
+}
diff --git a/virtual-patient-web/src/main/java/com/supervision/websocket/dto/NoResourceDTO.java b/virtual-patient-web/src/main/java/com/supervision/websocket/dto/NoResourceDTO.java
new file mode 100644
index 00000000..cbb32746
--- /dev/null
+++ b/virtual-patient-web/src/main/java/com/supervision/websocket/dto/NoResourceDTO.java
@@ -0,0 +1,10 @@
+package com.supervision.websocket.dto;
+
+import com.supervision.constant.UserTokenConstant;
+
+public class NoResourceDTO {
+
+    private final Integer code = UserTokenConstant.NO_RESOURCE_CODE;
+
+    private final String message = "用户被踢下线";
+}
diff --git a/virtual-patient-web/src/main/java/com/supervision/websocket/dto/UserWebSocketDTO.java b/virtual-patient-web/src/main/java/com/supervision/websocket/dto/UserWebSocketDTO.java
new file mode 100644
index 00000000..f57d46f6
--- /dev/null
+++ b/virtual-patient-web/src/main/java/com/supervision/websocket/dto/UserWebSocketDTO.java
@@ -0,0 +1,12 @@
+package com.supervision.websocket.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+@Data
+@AllArgsConstructor
+public class UserWebSocketDTO {
+
+    private String uuid;
+
+}
diff --git a/virtual-patient-web/src/main/java/com/supervision/websocket/dto/WebSocketLoginDTO.java b/virtual-patient-web/src/main/java/com/supervision/websocket/dto/WebSocketLoginDTO.java
new file mode 100644
index 00000000..f4d4e60c
--- /dev/null
+++ b/virtual-patient-web/src/main/java/com/supervision/websocket/dto/WebSocketLoginDTO.java
@@ -0,0 +1,28 @@
+package com.supervision.websocket.dto;
+
+import lombok.Data;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+
+@Data
+public class WebSocketLoginDTO {
+
+    private String userId;
+
+    private String uuid;
+
+    private String sessionId;
+
+    private String loginTime;
+
+    public WebSocketLoginDTO(String uuid, String userId, String sessionId) {
+        this.userId = userId;
+        this.uuid = uuid;
+        this.sessionId = sessionId;
+        this.loginTime = LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
+    }
+
+    public WebSocketLoginDTO() {
+    }
+}