From ce8c0386538ca18969fc3de7cff38959bf8ec304 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=8A=93=E8=9B=99=E5=B8=88?= <770492966@qq.com> Date: Thu, 30 Mar 2023 12:18:47 +0800 Subject: [PATCH] =?UTF-8?q?pr=EF=BC=9A=E5=A2=9E=E5=8A=A0webSocket=E6=94=AF?= =?UTF-8?q?=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 5 + ruoyi-demo/pom.xml | 5 + .../java/com/ruoyi/websocket/WebSocket.java | 150 ++++++++++++++++++ .../com/ruoyi/websocket/WebSocketConfig.java | 19 +++ ruoyi-ui/src/layout/components/Navbar.vue | 7 +- .../src/layout/components/WebSocket/index.vue | 108 +++++++++++++ 6 files changed, 293 insertions(+), 1 deletion(-) create mode 100644 ruoyi-demo/src/main/java/com/ruoyi/websocket/WebSocket.java create mode 100644 ruoyi-demo/src/main/java/com/ruoyi/websocket/WebSocketConfig.java create mode 100644 ruoyi-ui/src/layout/components/WebSocket/index.vue diff --git a/pom.xml b/pom.xml index 4a9450559..01c7d5287 100644 --- a/pom.xml +++ b/pom.xml @@ -83,6 +83,11 @@ + + org.springframework.boot + spring-boot-starter-websocket + ${spring-boot.version} + diff --git a/ruoyi-demo/pom.xml b/ruoyi-demo/pom.xml index b64625d34..ea7d49e45 100644 --- a/ruoyi-demo/pom.xml +++ b/ruoyi-demo/pom.xml @@ -17,6 +17,11 @@ + + org.springframework.boot + spring-boot-starter-websocket + + com.ruoyi diff --git a/ruoyi-demo/src/main/java/com/ruoyi/websocket/WebSocket.java b/ruoyi-demo/src/main/java/com/ruoyi/websocket/WebSocket.java new file mode 100644 index 000000000..b9ba9cc58 --- /dev/null +++ b/ruoyi-demo/src/main/java/com/ruoyi/websocket/WebSocket.java @@ -0,0 +1,150 @@ +package com.ruoyi.websocket; + +import cn.hutool.core.util.ObjectUtil; +import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.common.enums.UserType; +import com.ruoyi.common.helper.LoginHelper; +import com.ruoyi.common.utils.StringUtils; +import lombok.extern.slf4j.Slf4j; +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; + +/* + *@WebSocket + *@author ye + *@create 2023/3/30 9:45 + */ +@Slf4j +@Component +@ServerEndpoint("/webSocket/{token}") +public class WebSocket { + /* + * 存储session集合 + * */ + private static ConcurrentHashMap sessionMap = new ConcurrentHashMap<>(); + /** + * 存储用户集合 + */ + private static ConcurrentHashMap userMap = new ConcurrentHashMap<>(); + + + @OnOpen + public void onOpen(Session session, @PathParam(value = "token") String token){ + System.out.println("【webSocket连接成功】,token为:" + token); + LoginUser loginUser = LoginHelper.getLoginUser(token); + if (ObjectUtil.isNull(loginUser)) { + log.error("token失效或无法解析"); + } + setMap(session, loginUser); + + } + + private void setMap(Session session, LoginUser loginUser) { + //获取用户id + Long userId = loginUser.getUserId(); + //存储会话到会话集合 + sessionMap.put(userId, session); + //存储用户信息到用户集合 + userMap.put(userId, loginUser); + //获取会话大小 即在线人数 + int size = sessionMap.size(); + log.warn("用户连接:{},昵称:{},当前在线人数为:{}", userId, loginUser.getUsername(), size); + } + + @OnClose + public void onClose(Session session){ + System.out.println("【webSocket退出成功】" ); + removeMap(session); + } + + private void removeMap(Session session) { + Long userId = getUserIdBySession(session); + if (ObjectUtil.isNull(userId)) { + return; + } + sessionMap.remove(userId); + userMap.remove(userId); + } + + private Long getUserIdBySession(Session session) { + for (Long userId : sessionMap.keySet()) { + if (sessionMap.get(userId).getId().equals(session.getId())) { + return userId; + } + } + return null; + } + + @OnError + public void onError(Session session, Throwable throwable){ + + System.out.println("error:"); + throwable.printStackTrace(); + } + + @OnMessage + public void onMessage(Session session, String message){ + System.out.println("【webSocket接收成功】内容为:" + message); + LoginUser loginUser = getUserBySession(session); + if (ObjectUtil.isNull(loginUser)) { + return; + } + if (UserType.SYS_USER.getUserType().equals(loginUser.getUserType())) { + //系统用户 + handlePCMsg(loginUser, message); + }else { + //app + handleAPPMsg(loginUser, message); + } + + } + + private void handleAPPMsg(LoginUser loginUser, String message) { + log.info("APP用户:{},消息:", loginUser.getUsername(), message); + } + + private void handlePCMsg(LoginUser loginUser, String message) { + log.info("系统用户:{},消息:", loginUser.getUsername(), message); + } + + + private LoginUser getUserBySession(Session session) { + Long userId = getUserIdBySession(session); + if (ObjectUtil.isNull(userId)) { + return null; + } + return userMap.get(userId); + } + + + /** + * 发送自定义消息 + */ + public static void sendInfo(String message, Long toUserId) { + log.info("发送消息到:{},消息内容:{}", toUserId, message); + if (ObjectUtil.isNull(toUserId) || StringUtils.isBlank(message)) { + log.error("消息体不完整"); + return; + } + if (sessionMap.contains(toUserId)) { + try { + sendMessage(sessionMap.get(toUserId), message); + } catch (Exception e) { + log.error("发送给用户{}的消息出错", toUserId); + } + }else { + //用户不在线 + log.error("用户:{}不在线", toUserId); + //后续处理 + } + } + + public static void sendMessage(Session session, String message) throws IOException { + session.getBasicRemote().sendText(message); + } +} diff --git a/ruoyi-demo/src/main/java/com/ruoyi/websocket/WebSocketConfig.java b/ruoyi-demo/src/main/java/com/ruoyi/websocket/WebSocketConfig.java new file mode 100644 index 000000000..9c5344362 --- /dev/null +++ b/ruoyi-demo/src/main/java/com/ruoyi/websocket/WebSocketConfig.java @@ -0,0 +1,19 @@ +package com.ruoyi.websocket; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.stereotype.Component; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +/* + *@开启WebSocket支持 + *@author ye + *@create 2023/3/30 9:43 + */ +@Configuration +public class WebSocketConfig { + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } +} diff --git a/ruoyi-ui/src/layout/components/Navbar.vue b/ruoyi-ui/src/layout/components/Navbar.vue index 9de102c16..1e5ddf8c4 100644 --- a/ruoyi-ui/src/layout/components/Navbar.vue +++ b/ruoyi-ui/src/layout/components/Navbar.vue @@ -1,5 +1,8 @@