From 20af1c9acc9f083bfc20f684c9f57b75585ae86c Mon Sep 17 00:00:00 2001 From: AprilWind <2100166581@qq.com> Date: Wed, 10 Apr 2024 19:55:04 +0800 Subject: [PATCH] =?UTF-8?q?update=20=E4=BC=98=E5=8C=96=E5=B9=B6=E5=8F=91?= =?UTF-8?q?=E7=99=BB=E5=BD=95=E7=94=A8=E6=88=B7=E5=8F=AA=E8=83=BD=E6=8E=A5?= =?UTF-8?q?=E6=94=B6=E5=88=B0=E4=B8=80=E4=B8=AAws=E9=95=BF=E8=BF=9E?= =?UTF-8?q?=E6=8E=A5=E6=B6=88=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../web/controller/AuthController.java | 6 +-- .../common/satoken/utils/LoginHelper.java | 53 +++++++++++++++++++ .../constant/WebSocketConstants.java | 2 + .../websocket/dto/WebSocketMessageDto.java | 4 +- .../handler/PlusWebSocketHandler.java | 12 +++-- .../holder/WebSocketSessionHolder.java | 16 +++--- .../interceptor/PlusWebSocketInterceptor.java | 5 +- .../websocket/utils/WebSocketUtils.java | 8 +-- .../dromara/workflow/utils/WorkflowUtils.java | 3 +- 9 files changed, 88 insertions(+), 21 deletions(-) diff --git a/ruoyi-admin/src/main/java/org/dromara/web/controller/AuthController.java b/ruoyi-admin/src/main/java/org/dromara/web/controller/AuthController.java index 43e689be3..98528e2ec 100644 --- a/ruoyi-admin/src/main/java/org/dromara/web/controller/AuthController.java +++ b/ruoyi-admin/src/main/java/org/dromara/web/controller/AuthController.java @@ -95,11 +95,11 @@ public class AuthController { // 登录 LoginVo loginVo = IAuthStrategy.login(body, client, grantType); - Long userId = LoginHelper.getUserId(); + String tokenId = LoginHelper.getTokenId(); scheduledExecutorService.schedule(() -> { WebSocketMessageDto dto = new WebSocketMessageDto(); dto.setMessage("欢迎登录RuoYi-Vue-Plus后台管理系统"); - dto.setSessionKeys(List.of(userId)); + dto.setSessionKeys(List.of(tokenId)); WebSocketUtils.publishMessage(dto); }, 3, TimeUnit.SECONDS); return R.ok(loginVo); @@ -198,7 +198,7 @@ public class AuthController { } // 根据域名进行筛选 List list = StreamUtils.filter(voList, vo -> - StringUtils.equals(vo.getDomain(), host)); + StringUtils.equals(vo.getDomain(), host)); // 返回对象 LoginTenantVo vo = new LoginTenantVo(); vo.setVoList(CollUtil.isNotEmpty(list) ? list : voList); diff --git a/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/utils/LoginHelper.java b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/utils/LoginHelper.java index 21acfb1d1..b5c771912 100644 --- a/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/utils/LoginHelper.java +++ b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/utils/LoginHelper.java @@ -3,6 +3,7 @@ package org.dromara.common.satoken.utils; import cn.dev33.satoken.session.SaSession; import cn.dev33.satoken.stp.SaLoginModel; import cn.dev33.satoken.stp.StpUtil; +import cn.hutool.core.collection.CollUtil; import cn.hutool.core.convert.Convert; import cn.hutool.core.util.ObjectUtil; import lombok.AccessLevel; @@ -10,9 +11,13 @@ import lombok.NoArgsConstructor; import org.dromara.common.core.constant.TenantConstants; import org.dromara.common.core.constant.UserConstants; import org.dromara.common.core.domain.model.LoginUser; +import org.dromara.common.core.enums.DeviceType; import org.dromara.common.core.enums.UserType; +import java.util.Collections; +import java.util.List; import java.util.Set; +import java.util.stream.Collectors; /** * 登录鉴权助手 @@ -69,6 +74,54 @@ public class LoginHelper { return (LoginUser) session.get(LOGIN_USER_KEY); } + /** + * 获取当前登录用户的token + */ + public static String getTokenId() { + return StpUtil.getTokenInfo().getTokenValue() ; + } + + /** + * 获取当前用户的 token 集合 + */ + public static List getTokenIds() { + return StpUtil.getTokenValueListByLoginId(getUserId()); + } + + /** + * 获取当前用户 指定设备类型端的 token 集合 + */ + public static List getTokenIds(DeviceType device) { + return StpUtil.getTokenValueListByLoginId(getUserId(), device.getDevice()); + } + + /** + * 获取指定账号 userId 的 token 集合 + */ + public static List getTokenIds(Long userId) { + return StpUtil.getTokenValueListByLoginId(userId); + } + + /** + * 获取指定账号 userIds 的 token 集合 + */ + public static List getTokenUserIds(Set userIds) { + if (CollUtil.isNotEmpty(userIds)) { + return userIds.stream() + .flatMap(userId -> StpUtil.getTokenValueListByLoginId(userId).stream()) + .collect(Collectors.toList()); + } else { + return Collections.emptyList(); + } + } + + /** + * 获取指定账号 userId 指定设备类型端的 token 集合 + */ + public static List getTokenIds(Long userId, DeviceType device) { + return StpUtil.getTokenValueListByLoginId(userId, device.getDevice()); + } + /** * 获取用户基于token */ diff --git a/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/constant/WebSocketConstants.java b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/constant/WebSocketConstants.java index 54eb4470b..a700b335a 100644 --- a/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/constant/WebSocketConstants.java +++ b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/constant/WebSocketConstants.java @@ -6,10 +6,12 @@ package org.dromara.common.websocket.constant; * @author zendwang */ public interface WebSocketConstants { + /** * websocketSession中的参数的key */ String LOGIN_USER_KEY = "loginUser"; + String TOKEN_ID_KEY = "tokenId"; /** * 订阅的频道 diff --git a/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/dto/WebSocketMessageDto.java b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/dto/WebSocketMessageDto.java index e2d4456a0..3440988b1 100644 --- a/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/dto/WebSocketMessageDto.java +++ b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/dto/WebSocketMessageDto.java @@ -18,9 +18,9 @@ public class WebSocketMessageDto implements Serializable { private static final long serialVersionUID = 1L; /** - * 需要推送到的session key 列表 + * 需要推送到的session key 列表 一般为用户tokenId */ - private List sessionKeys; + private List sessionKeys; /** * 需要发送的消息 diff --git a/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/handler/PlusWebSocketHandler.java b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/handler/PlusWebSocketHandler.java index a53583f19..6b6b42bd5 100644 --- a/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/handler/PlusWebSocketHandler.java +++ b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/handler/PlusWebSocketHandler.java @@ -2,6 +2,7 @@ package org.dromara.common.websocket.handler; import lombok.extern.slf4j.Slf4j; import org.dromara.common.core.domain.model.LoginUser; +import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.common.websocket.dto.WebSocketMessageDto; import org.dromara.common.websocket.holder.WebSocketSessionHolder; import org.dromara.common.websocket.utils.WebSocketUtils; @@ -11,6 +12,7 @@ import org.springframework.web.socket.handler.AbstractWebSocketHandler; import java.util.List; import static org.dromara.common.websocket.constant.WebSocketConstants.LOGIN_USER_KEY; +import static org.dromara.common.websocket.constant.WebSocketConstants.TOKEN_ID_KEY; /** * WebSocketHandler 实现类 @@ -26,7 +28,8 @@ public class PlusWebSocketHandler extends AbstractWebSocketHandler { @Override public void afterConnectionEstablished(WebSocketSession session) { LoginUser loginUser = (LoginUser) session.getAttributes().get(LOGIN_USER_KEY); - WebSocketSessionHolder.addSession(loginUser.getUserId(), session); + String tokenId = (String) session.getAttributes().get(TOKEN_ID_KEY); + WebSocketSessionHolder.addSession(tokenId, session); log.info("[connect] sessionId: {},userId:{},userType:{}", session.getId(), loginUser.getUserId(), loginUser.getUserType()); } @@ -40,9 +43,9 @@ public class PlusWebSocketHandler extends AbstractWebSocketHandler { @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { LoginUser loginUser = (LoginUser) session.getAttributes().get(LOGIN_USER_KEY); - List userIds = List.of(loginUser.getUserId()); + List tokenIds = LoginHelper.getTokenIds(loginUser.getUserId()); WebSocketMessageDto webSocketMessageDto = new WebSocketMessageDto(); - webSocketMessageDto.setSessionKeys(userIds); + webSocketMessageDto.setSessionKeys(tokenIds); webSocketMessageDto.setMessage(message.getPayload()); WebSocketUtils.publishMessage(webSocketMessageDto); } @@ -85,7 +88,8 @@ public class PlusWebSocketHandler extends AbstractWebSocketHandler { @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus status) { LoginUser loginUser = (LoginUser) session.getAttributes().get(LOGIN_USER_KEY); - WebSocketSessionHolder.removeSession(loginUser.getUserId()); + String tokenId = (String) session.getAttributes().get(TOKEN_ID_KEY); + WebSocketSessionHolder.removeSession(tokenId); log.info("[disconnect] sessionId: {},userId:{},userType:{}", session.getId(), loginUser.getUserId(), loginUser.getUserType()); } diff --git a/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/holder/WebSocketSessionHolder.java b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/holder/WebSocketSessionHolder.java index de8c5a758..67580381a 100644 --- a/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/holder/WebSocketSessionHolder.java +++ b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/holder/WebSocketSessionHolder.java @@ -16,27 +16,31 @@ import java.util.concurrent.ConcurrentHashMap; @NoArgsConstructor(access = AccessLevel.PRIVATE) public class WebSocketSessionHolder { - private static final Map USER_SESSION_MAP = new ConcurrentHashMap<>(); + private static final Map USER_SESSION_MAP = new ConcurrentHashMap<>(); - public static void addSession(Long sessionKey, WebSocketSession session) { + /** + * @param sessionKey session主键 一般为用户tokenId + * @param session 会话 + */ + public static void addSession(String sessionKey, WebSocketSession session) { USER_SESSION_MAP.put(sessionKey, session); } - public static void removeSession(Long sessionKey) { + public static void removeSession(String sessionKey) { if (USER_SESSION_MAP.containsKey(sessionKey)) { USER_SESSION_MAP.remove(sessionKey); } } - public static WebSocketSession getSessions(Long sessionKey) { + public static WebSocketSession getSessions(String sessionKey) { return USER_SESSION_MAP.get(sessionKey); } - public static Set getSessionsAll() { + public static Set getSessionsAll() { return USER_SESSION_MAP.keySet(); } - public static Boolean existSession(Long sessionKey) { + public static Boolean existSession(String sessionKey) { return USER_SESSION_MAP.containsKey(sessionKey); } } diff --git a/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/interceptor/PlusWebSocketInterceptor.java b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/interceptor/PlusWebSocketInterceptor.java index 1dc4120db..4770945c1 100644 --- a/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/interceptor/PlusWebSocketInterceptor.java +++ b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/interceptor/PlusWebSocketInterceptor.java @@ -1,8 +1,8 @@ package org.dromara.common.websocket.interceptor; +import lombok.extern.slf4j.Slf4j; import org.dromara.common.core.domain.model.LoginUser; import org.dromara.common.satoken.utils.LoginHelper; -import lombok.extern.slf4j.Slf4j; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; import org.springframework.web.socket.WebSocketHandler; @@ -11,6 +11,7 @@ import org.springframework.web.socket.server.HandshakeInterceptor; import java.util.Map; import static org.dromara.common.websocket.constant.WebSocketConstants.LOGIN_USER_KEY; +import static org.dromara.common.websocket.constant.WebSocketConstants.TOKEN_ID_KEY; /** * WebSocket握手请求的拦截器 @@ -32,7 +33,9 @@ public class PlusWebSocketInterceptor implements HandshakeInterceptor { @Override public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map attributes) { LoginUser loginUser = LoginHelper.getLoginUser(); + String tokenId = LoginHelper.getTokenId(); attributes.put(LOGIN_USER_KEY, loginUser); + attributes.put(TOKEN_ID_KEY, tokenId); return true; } diff --git a/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/utils/WebSocketUtils.java b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/utils/WebSocketUtils.java index 086599c40..d8b0a4bf3 100644 --- a/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/utils/WebSocketUtils.java +++ b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/utils/WebSocketUtils.java @@ -31,10 +31,10 @@ public class WebSocketUtils { /** * 发送消息 * - * @param sessionKey session主键 一般为用户id + * @param sessionKey session主键 一般为用户tokenId * @param message 消息文本 */ - public static void sendMessage(Long sessionKey, String message) { + public static void sendMessage(String sessionKey, String message) { WebSocketSession session = WebSocketSessionHolder.getSessions(sessionKey); sendMessage(session, message); } @@ -54,9 +54,9 @@ public class WebSocketUtils { * @param webSocketMessage 消息对象 */ public static void publishMessage(WebSocketMessageDto webSocketMessage) { - List unsentSessionKeys = new ArrayList<>(); + List unsentSessionKeys = new ArrayList<>(); // 当前服务内session,直接发送消息 - for (Long sessionKey : webSocketMessage.getSessionKeys()) { + for (String sessionKey : webSocketMessage.getSessionKeys()) { if (WebSocketSessionHolder.existSession(sessionKey)) { WebSocketUtils.sendMessage(sessionKey, webSocketMessage.getMessage()); continue; diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/utils/WorkflowUtils.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/utils/WorkflowUtils.java index 6979671e2..03cac75fe 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/utils/WorkflowUtils.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/utils/WorkflowUtils.java @@ -12,6 +12,7 @@ import org.dromara.common.core.utils.StreamUtils; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.core.utils.reflect.ReflectUtils; import org.dromara.common.mail.utils.MailUtils; +import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.common.tenant.helper.TenantHelper; import org.dromara.common.websocket.dto.WebSocketMessageDto; import org.dromara.common.websocket.utils.WebSocketUtils; @@ -324,7 +325,7 @@ public class WorkflowUtils { switch (messageTypeEnum) { case SYSTEM_MESSAGE: WebSocketMessageDto dto = new WebSocketMessageDto(); - dto.setSessionKeys(new ArrayList<>(userIds)); + dto.setSessionKeys(LoginHelper.getTokenUserIds(userIds)); dto.setMessage(message); WebSocketUtils.publishMessage(dto); break;