From 58d6f15cc4502c94595a915007e400b76fbb295e Mon Sep 17 00:00:00 2001
From: liuhanqing <447067298@qq.com>
Date: Sun, 24 Jan 2021 23:25:46 +0800
Subject: [PATCH] =?UTF-8?q?=E3=80=90message=E3=80=91=E6=B6=88=E6=81=AF?=
=?UTF-8?q?=E6=A8=A1=E5=9D=97=E5=A2=9E=E5=8A=A0websocket?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../message-sdk-websocket/README.md | 1 +
.../message-sdk-websocket/pom.xml | 35 +++++++
.../websocket/manager/WebSocketManager.java | 95 +++++++++++++++++++
.../websocket/server/WebSocketEndpoint.java | 78 +++++++++++++++
.../message-spring-boot-starter/pom.xml | 5 +
.../starter/GunsMessageAutoConfiguration.java | 16 +++-
kernel-s-message/pom.xml | 1 +
7 files changed, 230 insertions(+), 1 deletion(-)
create mode 100644 kernel-s-message/message-sdk-websocket/README.md
create mode 100644 kernel-s-message/message-sdk-websocket/pom.xml
create mode 100644 kernel-s-message/message-sdk-websocket/src/main/java/cn/stylefeng/roses/kernel/message/websocket/manager/WebSocketManager.java
create mode 100644 kernel-s-message/message-sdk-websocket/src/main/java/cn/stylefeng/roses/kernel/message/websocket/server/WebSocketEndpoint.java
diff --git a/kernel-s-message/message-sdk-websocket/README.md b/kernel-s-message/message-sdk-websocket/README.md
new file mode 100644
index 000000000..c3097283d
--- /dev/null
+++ b/kernel-s-message/message-sdk-websocket/README.md
@@ -0,0 +1 @@
+系统消息websocket的sdk,用于将消息发送给在线用户,并提供相应接口
\ No newline at end of file
diff --git a/kernel-s-message/message-sdk-websocket/pom.xml b/kernel-s-message/message-sdk-websocket/pom.xml
new file mode 100644
index 000000000..0bc7a8c83
--- /dev/null
+++ b/kernel-s-message/message-sdk-websocket/pom.xml
@@ -0,0 +1,35 @@
+
+
+ 4.0.0
+
+
+ cn.stylefeng.roses
+ kernel-s-message
+ 1.0.0
+ ../pom.xml
+
+
+ message-sdk-websocket
+
+ jar
+
+
+
+
+
+ cn.stylefeng.roses
+ message-api
+ 1.0.0
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-websocket
+
+
+
+
+
diff --git a/kernel-s-message/message-sdk-websocket/src/main/java/cn/stylefeng/roses/kernel/message/websocket/manager/WebSocketManager.java b/kernel-s-message/message-sdk-websocket/src/main/java/cn/stylefeng/roses/kernel/message/websocket/manager/WebSocketManager.java
new file mode 100644
index 000000000..2d7d93dc8
--- /dev/null
+++ b/kernel-s-message/message-sdk-websocket/src/main/java/cn/stylefeng/roses/kernel/message/websocket/manager/WebSocketManager.java
@@ -0,0 +1,95 @@
+package cn.stylefeng.roses.kernel.message.websocket.manager;
+
+import org.springframework.util.CollectionUtils;
+
+import javax.websocket.Session;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * @author liuhq
+ */
+public class WebSocketManager {
+ private static final ConcurrentHashMap> userIdSessionMap = new ConcurrentHashMap<>();
+
+ /**
+ * 添加用户ID相关的Session
+ *
+ * @param userId 用户id
+ * @param session 用户websocketSession
+ * @author liuhanqing
+ * @date 2021/1/24 22:08
+ */
+ public static void add(Long userId, Session session) {
+ userIdSessionMap.computeIfAbsent(userId, v -> new ArrayList<>()).add(session);
+ }
+
+ /**
+ * 根据用户ID获取Session
+ *
+ * @param userId 用户id
+ * @return List 用户websocketSession集合
+ * @author liuhanqing
+ * @date 2021/1/24 22:10
+ */
+ public static List getSessionByUserId(Long userId) {
+ return userIdSessionMap.get(userId);
+ }
+
+ /**
+ * 移除失效的Session
+ *
+ * @param userId 用户id
+ * @param session 用户websocketSession
+ * @author liuhanqing
+ * @date 2021/1/24 22:11
+ */
+ public static void removeSession(Long userId, Session session) {
+ if (session == null) {
+ return;
+ }
+ List webSessoin = userIdSessionMap.get(userId);
+ if (webSessoin == null || CollectionUtils.isEmpty(webSessoin)) {
+ return;
+ }
+ webSessoin.remove(session);
+ }
+
+ /**
+ * 获取链接用户集合
+ *
+ * @author liuhanqing
+ * @date 2021/1/24 22:11
+ */
+ public static Set getUserList() {
+ return userIdSessionMap.keySet();
+ }
+
+ /**
+ * 发送消息
+ *
+ * @param userId 用户id
+ * @param message 消息
+ * @author liuhanqing
+ * @date 2021/1/24 22:11
+ */
+ public static void sendMessage(Long userId, String message){
+ for(Session userSession: getSessionByUserId(userId)){
+ userSession.getAsyncRemote().sendText(message);
+ }
+ }
+ /**
+ * 发送消息
+ *
+ * @param message 消息
+ * @author liuhanqing
+ * @date 2021/1/24 22:11
+ */
+ public static void sendMessageToAll(String message){
+ for (Long userId : WebSocketManager.getUserList()) {
+ sendMessage(userId, message);
+ }
+ }
+}
diff --git a/kernel-s-message/message-sdk-websocket/src/main/java/cn/stylefeng/roses/kernel/message/websocket/server/WebSocketEndpoint.java b/kernel-s-message/message-sdk-websocket/src/main/java/cn/stylefeng/roses/kernel/message/websocket/server/WebSocketEndpoint.java
new file mode 100644
index 000000000..97fe3d064
--- /dev/null
+++ b/kernel-s-message/message-sdk-websocket/src/main/java/cn/stylefeng/roses/kernel/message/websocket/server/WebSocketEndpoint.java
@@ -0,0 +1,78 @@
+package cn.stylefeng.roses.kernel.message.websocket.server;
+
+import cn.stylefeng.roses.kernel.message.websocket.manager.WebSocketManager;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import javax.websocket.*;
+import javax.websocket.server.PathParam;
+import javax.websocket.server.ServerEndpoint;
+
+/**
+ * websocket服务端
+ *
+ * @author liuhanqing
+ * @date 2021/1/24 22:26
+ */
+@Slf4j
+@Component
+@ServerEndpoint("/message/websocket/{userId}")
+public class WebSocketEndpoint {
+
+
+ /**
+ * 连接建立成功后调用
+ *
+ * @param userId 用户id
+ * @param session 用户websocketSession
+ * @author liuhanqing
+ * @date 2021/1/24 22:27
+ */
+ @OnOpen
+ public void onOpen(@PathParam(value = "userId") Long userId, Session session) {
+ // 添加到链接管理
+ WebSocketManager.add(userId, session);
+ // 返回消息
+ session.getAsyncRemote().sendText("WebSocket连接成功");
+ }
+
+ /**
+ * 连接关闭时调用
+ *
+ * @author liuhanqing
+ * @date 2021/1/24 22:29
+ */
+ @OnClose
+ public void onClose(@PathParam(value = "userId") Long userId, Session session) {
+ // 从map中删除
+ WebSocketManager.removeSession(userId, session);
+ }
+
+ /**
+ * 收到客户端消息后调用
+ *
+ * @param message 客户端发送过来的消息
+ * @param session 用户websocketSession
+ * @author liuhanqing
+ * @date 2021/1/24 22:29
+ */
+ @OnMessage
+ public void onMessage(String message, Session session) {
+ log.info("来自客户端的消息:" + message);
+ }
+
+ /**
+ * 发生错误时回调
+ *
+ * @param session 用户信息
+ * @param error 错误
+ * @author liuhanqing
+ * @date 2021/1/24 22:29
+ */
+ @OnError
+ public void onError(Session session, Throwable error) {
+ log.error("WebSocket发生错误");
+ error.printStackTrace();
+ }
+
+}
\ No newline at end of file
diff --git a/kernel-s-message/message-spring-boot-starter/pom.xml b/kernel-s-message/message-spring-boot-starter/pom.xml
index 4f3ad1332..8e524f516 100644
--- a/kernel-s-message/message-spring-boot-starter/pom.xml
+++ b/kernel-s-message/message-spring-boot-starter/pom.xml
@@ -32,6 +32,11 @@
1.0.0
+
+ cn.stylefeng.roses
+ message-sdk-websocket
+ 1.0.0
+
diff --git a/kernel-s-message/message-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/message/starter/GunsMessageAutoConfiguration.java b/kernel-s-message/message-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/message/starter/GunsMessageAutoConfiguration.java
index a2c26e978..4ff570dfe 100644
--- a/kernel-s-message/message-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/message/starter/GunsMessageAutoConfiguration.java
+++ b/kernel-s-message/message-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/message/starter/GunsMessageAutoConfiguration.java
@@ -1,6 +1,9 @@
package cn.stylefeng.roses.kernel.message.starter;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
+import org.springframework.web.socket.server.standard.ServerEndpointExporter;
/**
* 系统消息的自动配置
@@ -11,6 +14,17 @@ import org.springframework.context.annotation.Configuration;
@Configuration
public class GunsMessageAutoConfiguration {
-
+ /**
+ * 开启WebSocket功能
+ *
+ * @return serverEndpointExporter
+ * @author liuhanqing
+ * @date 2021/01/24 22:09
+ */
+ @Bean
+ @ConditionalOnMissingBean(ServerEndpointExporter.class)
+ public ServerEndpointExporter serverEndpointExporter() {
+ return new ServerEndpointExporter();
+ }
}
\ No newline at end of file
diff --git a/kernel-s-message/pom.xml b/kernel-s-message/pom.xml
index 728ea6b52..b3c1b9155 100644
--- a/kernel-s-message/pom.xml
+++ b/kernel-s-message/pom.xml
@@ -19,6 +19,7 @@
message-api
message-business
message-sdk-db
+ message-sdk-websocket
message-spring-boot-starter