问诊大厅代码提交

dev_2.0.0
liu
parent 6f91973c8e
commit 25450fc781

@ -58,27 +58,6 @@ public class JwtInterceptor implements HandlerInterceptor {
return true;
}
public void checkSingleLogin(String userId, JWT currentJwt) {
if (Boolean.FALSE.equals(redisTemplate.hasKey(UserTokenConstant.TOKEN_CACHE + userId))) {
throw new BusinessException("用户已被踢下线或超时,请重新登录", 505);
}
String value = redisTemplate.opsForValue().get(UserTokenConstant.TOKEN_CACHE + userId);
long redisCacheTime = Long.parseLong(String.valueOf(value));
Object currentJwtIssueTimeObject = currentJwt.getPayload("issueTime");
long currentJwtIssueTime = Long.parseLong(String.valueOf(currentJwtIssueTimeObject));
if (redisCacheTime == currentJwtIssueTime) {
// 如果相等,说明这个token就是最新的,直接放行
return;
} else if (currentJwtIssueTime > redisCacheTime) {
// 如果当前请求时间,大于Redis缓存时间,说明重新登录了,这个时候要把最新的放到缓存中
redisTemplate.opsForValue().set(UserTokenConstant.TOKEN_CACHE + userId, String.valueOf(System.currentTimeMillis()), 1000 * 5L, TimeUnit.MILLISECONDS);
} else {
// 走到这里,说明redisCacheTime是最新的,说明当前用户请求了一个新的token,那么原来的用户就踢掉
throw new BusinessException("当前用户已在其他地方登录!", 505);
}
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,

@ -1,9 +1,6 @@
package com.supervision.constant;
public interface UserTokenConstant {
String TOKEN_CACHE = "USER:LOGIN:TOKEN:";
String USER_ID_CACHE = "USER:ID:CACHE";
String KICK_CHANNEL = "USER:KICK:CHANNEL";

@ -43,19 +43,9 @@ public class UserController {
throw new BusinessException("密码错误");
}
String token = TokenUtil.creatToken(JSONUtil.toJsonStr(user.get()));
// 将用户的token保存起来,超时时间为5分钟
redisTemplate.opsForValue().set(UserTokenConstant.TOKEN_CACHE + user.get().getId(), String.valueOf(System.currentTimeMillis()), 1000 * 5L, TimeUnit.MILLISECONDS);
return token;
}
@ApiOperation("token心跳")
@PostMapping("keepaliveToken")
public void keepaliveToken() {
User user = UserUtil.getUser();
// 每次心跳都设置为5分钟之后
redisTemplate.expire(UserTokenConstant.TOKEN_CACHE + user.getId(), 1000 * 5L, TimeUnit.MILLISECONDS);
}
@ApiOperation("踢用户下线")
@GetMapping("kickUser")
public void kickUser(String userId) {

@ -1,7 +1,10 @@
package com.supervision.controller;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.supervision.constant.UserTokenConstant;
import com.supervision.usermanage.UserWebSocketDTO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@ -29,10 +32,12 @@ public class WebSocketServer {
*
*/
@OnOpen
public void onOpen(Session session, @PathParam(value = "uid") String uid) {
public void onOpen(Session session, @PathParam(value = "uid") String uid) throws IOException {
log.info("用户:{}登录,缓存到Redis", uid);
// 链接之前先把之前的用户踢下线(ignoreSessionId防止把当前用户踢下线)
redisTemplate.convertAndSend(UserTokenConstant.KICK_CHANNEL, JSONUtil.toJsonStr(new UserWebSocketDTO(uid, session.getId())));
SESSION_POOL.put(uid, session);
redisTemplate.opsForSet().add(UserTokenConstant.USER_ID_CACHE, uid);
redisTemplate.opsForHash().put(UserTokenConstant.USER_ID_CACHE, uid, session.getId());
}
/**
@ -40,9 +45,9 @@ public class WebSocketServer {
*/
@OnClose
public void onClose(Session session, @PathParam(value = "uid") String uid) {
redisTemplate.opsForSet().remove(UserTokenConstant.USER_ID_CACHE, uid);
redisTemplate.opsForHash().delete(UserTokenConstant.USER_ID_CACHE, uid, session.getId());
SESSION_POOL.remove(uid);
log.info("用户:{}关闭从Redis中移除,当前连接数为:{}", uid, redisTemplate.opsForSet().size(UserTokenConstant.USER_ID_CACHE));
log.info("用户:{}关闭从Redis中移除,当前连接数为:{}", uid, redisTemplate.opsForHash().size(UserTokenConstant.USER_ID_CACHE));
}
/**
@ -50,18 +55,20 @@ public class WebSocketServer {
*/
@OnError
public void onError(Session session, @PathParam(value = "uid") String uid, Throwable throwable) {
redisTemplate.opsForSet().remove(UserTokenConstant.USER_ID_CACHE, uid);
redisTemplate.opsForHash().delete(UserTokenConstant.USER_ID_CACHE, uid, session.getId());
SESSION_POOL.remove(uid);
log.error("用户:{}发生错误从Redis中移除,当前连接数为:{}", uid, redisTemplate.opsForSet().size(UserTokenConstant.USER_ID_CACHE), throwable);
log.error("用户:{}发生错误从Redis中移除,当前连接数为:{}", uid, redisTemplate.opsForHash().size(UserTokenConstant.USER_ID_CACHE), throwable);
}
// 实现一个方法用于踢下线用户,走的是Redis的消息队列
public void kickUser(String userId) throws IOException {
public void kickUser(String userId, String ignoreSessionId) throws IOException {
log.info("尝试主动踢用户:{}下线", userId);
Session session = SESSION_POOL.get(userId);
if (ObjectUtil.isNotEmpty(session)) {
// 只有不是忽略剔除的sessionId才可以踢下线
if (ObjectUtil.isNotEmpty(session) && !StrUtil.equals(ignoreSessionId, session.getId())) {
session.close(new CloseReason(CloseReason.CloseCodes.NORMAL_CLOSURE, "用户被踢下线"));
log.info("主动踢用户:{}下线成功", userId);
SESSION_POOL.remove(userId);
log.info("主动踢用户:{},sessionId:{} 下线成功", userId, session.getId());
return;
}
log.info("主动踢用户:{}下线,未找到用户,踢下线失败", userId);

@ -23,11 +23,8 @@ public class DiagnoseHallServiceImpl implements DiagnoseHallService {
@Override
public boolean achieveDiagnoseResource() {
long humanMaxNumber = Long.parseLong(resourceNumber);
Long currentUserNum = redisTemplate.opsForSet().size(UserTokenConstant.USER_ID_CACHE);
long currentUserNum = redisTemplate.opsForHash().size(UserTokenConstant.USER_ID_CACHE);
// 如果小于数字人最大连接数,则可以连接
if (null == currentUserNum){
return true;
}
return currentUserNum <= humanMaxNumber;
}
}

@ -1,5 +1,6 @@
package com.supervision.usermanage;
import cn.hutool.json.JSONUtil;
import com.supervision.constant.UserTokenConstant;
import com.supervision.controller.WebSocketServer;
import lombok.extern.slf4j.Slf4j;
@ -20,10 +21,11 @@ public class KickUserListener implements MessageListener {
@Override
public void onMessage(Message message, byte[] pattern) {
String userId = message.toString();
log.info("Redis的Channel:{}收到踢用户下线消息:{}", UserTokenConstant.KICK_CHANNEL, userId);
String messageString = message.toString();
UserWebSocketDTO user = JSONUtil.toBean(messageString, UserWebSocketDTO.class);
log.info("Redis的Channel:{}收到踢用户{}下线消息", UserTokenConstant.KICK_CHANNEL, user.getUserId());
try {
webSocketServer.kickUser(userId);
webSocketServer.kickUser(user.getUserId(), user.getIgnoreSessionId());
} catch (IOException e) {
throw new RuntimeException(e);
}

@ -0,0 +1,16 @@
package com.supervision.usermanage;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class UserWebSocketDTO {
private String userId;
/**
* ID
*/
private String ignoreSessionId;
}
Loading…
Cancel
Save