tangbin пре 10 месеци
родитељ
комит
6b8480f264

+ 4 - 0
yezhu-api/pom.xml

@@ -46,6 +46,10 @@
 			<artifactId>qiniu-java-sdk</artifactId>
 			<version>7.2.27</version>
 		</dependency>
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-websocket</artifactId>
+		</dependency>
     </dependencies>
 
 	<build>

+ 5 - 1
yezhu-api/src/main/java/com/kioor/ApiApplication.java

@@ -12,6 +12,8 @@ import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.builder.SpringApplicationBuilder;
 import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
+import org.springframework.context.ConfigurableApplicationContext;
+import com.kioor.websocket.WebSocketServer;
 
 /**
  * yezhu-api
@@ -22,7 +24,9 @@ import org.springframework.boot.web.servlet.support.SpringBootServletInitializer
 public class ApiApplication extends SpringBootServletInitializer {
 
 	public static void main(String[] args) {
-		SpringApplication.run(ApiApplication.class, args);
+//		SpringApplication.run(ApiApplication.class, args);
+		ConfigurableApplicationContext run = SpringApplication.run(ApiApplication.class, args);
+		WebSocketServer.setApplicationContext(run);
 	}
 
 	@Override

+ 137 - 0
yezhu-api/src/main/java/com/kioor/websocket/WebSocketServer.java

@@ -0,0 +1,137 @@
+/**
+ * Copyright (c) 2016-2020 业主系统 All rights reserved.
+ * <p>
+ * https://www.yezhu.io
+ * <p>
+ * 版权所有,侵权必究!
+ */
+
+package com.kioor.websocket;
+
+import com.kioor.common.exception.ErrorCode;
+import com.kioor.common.exception.RenException;
+import com.kioor.common.utils.JsonUtils;
+import com.kioor.user.entity.TokenEntity;
+import com.kioor.user.service.TokenService;
+import com.kioor.websocket.config.WebSocketConfig;
+import com.kioor.websocket.data.MessageData;
+import com.kioor.websocket.data.WebSocketData;
+import jakarta.websocket.*;
+import jakarta.websocket.server.PathParam;
+import jakarta.websocket.server.ServerEndpoint;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.context.ApplicationContext;
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * WebSocket服务
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Slf4j
+@Component
+@ServerEndpoint(value = "/websocket/{token}", configurator = WebSocketConfig.class)
+public class WebSocketServer {
+
+    private static ApplicationContext applicationContext;
+
+    public static void setApplicationContext(ApplicationContext applicationContext) {
+        WebSocketServer.applicationContext = applicationContext;
+    }
+    /**
+     * 客户端连接信息
+     */
+    private static Map<String, WebSocketData> servers = new ConcurrentHashMap<>();
+    /**
+     * 存放所有在线的客户端
+     */
+    private static Map<Long, Session> clients = new ConcurrentHashMap<>();
+
+    @OnOpen
+    public void open(@PathParam("token") String token,Session session) {
+//        Long userId = (Long) session.getUserProperties().get(Constant.USER_KEY);
+        TokenService tokenService = applicationContext.getBean(TokenService.class);
+
+        //通过token查找用户id
+        TokenEntity tokenEntity = tokenService.getByToken(token);
+        if (tokenEntity == null || tokenEntity.getExpireDate().getTime() < System.currentTimeMillis()) {
+            throw new RenException(ErrorCode.TOKEN_INVALID);
+        }
+        if(clients.containsKey(tokenEntity.getUserId())){
+            servers.remove(clients.get(tokenEntity.getUserId()).getId());
+            clients.remove(tokenEntity.getUserId());
+        }
+        servers.put(session.getId(), new WebSocketData(tokenEntity.getUserId(), session));
+        clients.put(tokenEntity.getUserId(), session);
+    }
+
+    @OnClose
+    public void onClose(Session session) {
+        //客户端断开连接
+        servers.remove(session.getId());
+        log.debug("websocket close, session id:" + session.getId());
+    }
+
+    @OnError
+    public void onError(Session session, Throwable throwable) {
+        servers.remove(session.getId());
+        log.error(throwable.getMessage(), throwable);
+    }
+
+    @OnMessage
+    public void onMessage(Session session, String msg) {
+        log.info("session id: " + session.getId() + ", message:" + msg);
+
+        MessageData<String> message = new MessageData<String>().msg("你说啥子");
+//        List<Long> userIdList = new ArrayList<>();
+//        userIdList.add(1806260428364058625L);
+//        sendMessage(userIdList, message);
+        sendMessage(1806260428364058625L, message);
+    }
+
+    /**
+     * 发送信息
+     *
+     * @param userIdList 用户ID列表
+     * @param message    消息内容
+     */
+    public void sendMessage(List<Long> userIdList, MessageData<?> message) {
+        userIdList.forEach(userId -> sendMessage(userId, message));
+    }
+
+    /**
+     * 发送信息
+     *
+     * @param userId  用户ID
+     * @param message 消息内容
+     */
+    public void sendMessage(Long userId, MessageData<?> message) {
+        servers.values().forEach(info -> {
+            if (userId.equals(info.getUserId())) {
+                sendMessage(info.getSession(), message);
+            }
+        });
+    }
+
+    /**
+     * 发送信息给全部用户
+     *
+     * @param message 消息内容
+     */
+    public void sendMessageAll(MessageData<?> message) {
+        servers.values().forEach(info -> sendMessage(info.getSession(), message));
+    }
+
+    public void sendMessage(Session session, MessageData<?> message) {
+        try {
+            session.getBasicRemote().sendText(JsonUtils.toJsonString(message));
+        } catch (IOException e) {
+            log.error("send message error," + e.getMessage(), e);
+        }
+    }
+}

+ 35 - 0
yezhu-api/src/main/java/com/kioor/websocket/config/WebSocketConfig.java

@@ -0,0 +1,35 @@
+/**
+ * Copyright (c) 2016-2020 业主系统 All rights reserved.
+ * <p>
+ * https://www.yezhu.io
+ * <p>
+ * 版权所有,侵权必究!
+ */
+
+package com.kioor.websocket.config;
+
+import jakarta.websocket.HandshakeResponse;
+import jakarta.websocket.server.HandshakeRequest;
+import jakarta.websocket.server.ServerEndpointConfig;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.socket.server.standard.ServerEndpointExporter;
+
+/**
+ * WebSocket配置
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Configuration
+public class WebSocketConfig extends ServerEndpointConfig.Configurator {
+    @Bean
+    public ServerEndpointExporter serverEndpointExporter() {
+        return new ServerEndpointExporter();
+    }
+
+    @Override
+    public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
+//        sec.getUserProperties().put(Constant.USER_KEY, SecurityUser.getUserId());
+    }
+
+}

+ 43 - 0
yezhu-api/src/main/java/com/kioor/websocket/data/MessageData.java

@@ -0,0 +1,43 @@
+/**
+ * Copyright (c) 2016-2020 业主系统 All rights reserved.
+ * <p>
+ * https://www.yezhu.io
+ * <p>
+ * 版权所有,侵权必究!
+ */
+
+package com.kioor.websocket.data;
+
+import lombok.Data;
+
+/**
+ * 响应客户端数据
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Data
+public class MessageData<T> {
+    /**
+     * 编码  0:文本消息  1:对象消息
+     */
+    private int type = 0;
+    /**
+     * 文本消息
+     */
+    private String msg;
+    /**
+     * 对象消息
+     */
+    private T data;
+
+    public MessageData<T> data(T data) {
+        this.setData(data);
+        this.type = 1;
+        return this;
+    }
+
+    public MessageData<T> msg(String msg) {
+        this.msg = msg;
+        return this;
+    }
+}

+ 26 - 0
yezhu-api/src/main/java/com/kioor/websocket/data/WebSocketData.java

@@ -0,0 +1,26 @@
+/**
+ * Copyright (c) 2016-2020 业主系统 All rights reserved.
+ * <p>
+ * https://www.yezhu.io
+ * <p>
+ * 版权所有,侵权必究!
+ */
+
+package com.kioor.websocket.data;
+
+import jakarta.websocket.Session;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+
+/**
+ * WebSocket连接数据
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+@Data
+@AllArgsConstructor
+public class WebSocketData {
+    private Long userId;
+    private Session session;
+}

+ 41 - 0
yezhu-api/src/main/java/com/kioor/websocket/dto/UserWebSocket.java

@@ -0,0 +1,41 @@
+package com.kioor.websocket.dto;
+
+import lombok.Data;
+
+/**
+ * 项目名称: toby-yezhu
+ * 文件名称: UserWebSocket
+ * 描述: socket传递用户信息中间类
+ * <p>
+ * 创建人: 唐斌
+ * 创建时间: 2024/7/5
+ * <p>
+ * 版权所有 © 2024 TANG BIN. All Rights Reserved.
+ */
+@Data
+public class UserWebSocket {
+    /**
+     * 用户ID
+     */
+    private String id;
+    /**
+     * 用户名
+     */
+    private String username;
+    /**
+     * 手机号
+     */
+    private String mobile;
+    /**
+     * 等级
+     */
+    private String level;
+    /**
+     * 签名
+     */
+    private String remarks;
+    /**
+     * 房号
+     */
+    private String roomStr;
+}