liurunyu
2025-02-11 7b119de9ee015934f8b001b6038e282522993c80
远程模块实现websocket基本框架
4个文件已添加
11个文件已修改
253 ■■■■■ 已修改文件
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/webUtil/WebSocketMessage.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/resources/application-global(166web文件花生壳).yml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/resources/application-global(mj梅江系统).yml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/resources/application-global(mq民勤系统).yml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/resources/application-global(sp沙盘系统).yml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/resources/application-global(test测试系统).yml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/resources/application-global(ym元谋系统).yml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/resources/application-global.yml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/pom.xml 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/PipIrrRemoteApplication.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/config/WebSocketConfig.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/largeScreen/WebSocketHeartBeat.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/largeScreen/WebSocketServer.java 131 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pom.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pom.xml 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/webUtil/WebSocketMessage.java
New file
@@ -0,0 +1,33 @@
package com.dy.common.webUtil;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
 * @Author: liurunyu
 * @Date: 2025/2/11 10:41
 * @Description
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Schema(name="websocket消息基类")
@JsonPropertyOrder({"type", "code", "content"})
public class WebSocketMessage<T> {
    @Schema(description = "数据类型")
    public String type;
    @Schema(description = "数据编码")
    public String code;//数据编码,具体数据具体定义其编码,可以为空
    @Schema(description = "数据")
    public T content;
    public static final String TYPE_HEARTBEAT = "HEARTBEAT";//心跳,也是文本数据,数据内容是服务端时刻
    public static final String TYPE_TEXT = "TEXT";//文本数据
    public static final String TYPE_JSON = "JSON";//json数据
}
pipIrr-platform/pipIrr-global/src/main/resources/application-global(166webÎļþ»¨Éú¿Ç).yml
@@ -348,6 +348,7 @@
        - /sso/sso
        - /remote/comRes/receive
        - /remote/rtuUpgradeStateReceiver/receive
        - /remote/websocket
        - /wx/comRes/receive
        - /app/captcha/get
        - /file/file #web分布式文件系统
pipIrr-platform/pipIrr-global/src/main/resources/application-global(mj÷½­ÏµÍ³).yml
@@ -348,6 +348,7 @@
        - /sso/sso
        - /remote/comRes/receive
        - /remote/rtuUpgradeStateReceiver/receive
        - /remote/websocket
        - /wx/comRes/receive
        - /app/captcha/get
        - /file/file #web分布式文件系统
pipIrr-platform/pipIrr-global/src/main/resources/application-global(mqÃñÇÚϵͳ).yml
@@ -348,6 +348,7 @@
        - /sso/sso
        - /remote/comRes/receive
        - /remote/rtuUpgradeStateReceiver/receive
        - /remote/websocket
        - /wx/comRes/receive
        - /app/captcha/get
        - /file/file #web分布式文件系统
pipIrr-platform/pipIrr-global/src/main/resources/application-global(spɳÅÌϵͳ).yml
@@ -348,6 +348,7 @@
        - /sso/sso
        - /remote/comRes/receive
        - /remote/rtuUpgradeStateReceiver/receive
        - /remote/websocket
        - /wx/comRes/receive
        - /app/captcha/get
        - /file/file #web分布式文件系统
pipIrr-platform/pipIrr-global/src/main/resources/application-global(test²âÊÔϵͳ).yml
@@ -348,6 +348,7 @@
        - /sso/sso
        - /remote/comRes/receive
        - /remote/rtuUpgradeStateReceiver/receive
        - /remote/websocket
        - /wx/comRes/receive
        - /app/captcha/get
        - /file/file #web分布式文件系统
pipIrr-platform/pipIrr-global/src/main/resources/application-global(ymԪıϵͳ).yml
@@ -348,6 +348,7 @@
        - /sso/sso
        - /remote/comRes/receive
        - /remote/rtuUpgradeStateReceiver/receive
        - /remote/websocket
        - /wx/comRes/receive
        - /app/captcha/get
        - /file/file #web分布式文件系统
pipIrr-platform/pipIrr-global/src/main/resources/application-global.yml
@@ -348,6 +348,7 @@
        - /sso/sso
        - /remote/comRes/receive
        - /remote/rtuUpgradeStateReceiver/receive
        - /remote/websocket
        - /wx/comRes/receive
        - /app/captcha/get
        - /file/file #web分布式文件系统
pipIrr-platform/pipIrr-web/pipIrr-web-remote/pom.xml
@@ -9,12 +9,7 @@
            <version>1.0.0</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>com.dy</groupId>
            <artifactId>pipIrr-web-sell</artifactId>
            <version>1.0.0</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>
    <parent>
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/PipIrrRemoteApplication.java
@@ -8,7 +8,12 @@
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.annotation.FilterType;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@EnableScheduling //启动定时任务,本模块websocket发送心跳
@ServletComponentScan //扫描servlet,本模块中启动websocket
@EnableAspectJAutoProxy
@EnableMultiDataSource
@ComponentScan(basePackages = {"com.dy.common", "com.dy.pipIrrGlobal", "com.dy.pipIrrRemote"},
@@ -23,7 +28,8 @@
        "com.dy.pipIrrGlobal.daoSe",
        "com.dy.pipIrrGlobal.daoBa",
        "com.dy.pipIrrGlobal.daoFi",
        "com.dy.pipIrrGlobal.daoAllRound"
        "com.dy.pipIrrGlobal.daoAllRound",
        "com.dy.pipIrrGlobal.daoLargeScreen"
})
public class PipIrrRemoteApplication {
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/config/WebSocketConfig.java
New file
@@ -0,0 +1,19 @@
package com.dy.pipIrrRemote.config;
/**
 * @Author: liurunyu
 * @Date: 2025/2/10 15:42
 * @Description
 */
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
//开启WebSocket的支持,并把该类注入到spring容器中
@Configuration
public class WebSocketConfig {
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/largeScreen/WebSocketHeartBeat.java
New file
@@ -0,0 +1,32 @@
package com.dy.pipIrrRemote.largeScreen;
/**
 * @Author: liurunyu
 * @Date: 2025/2/11 8:37
 * @Description
 */
import com.alibaba.fastjson2.JSON;
import com.dy.common.util.DateTime;
import com.dy.common.webUtil.WebSocketMessage;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class WebSocketHeartBeat {
    // è®¾ç½®å®šæ—¶åç§’一次
    @Scheduled(cron = "0/10 * * * * ?")
    public void WsHeartBeat() throws Exception {
        WebSocketServer.sendAllMessage(getHeartBeatMessage());
    }
    public static String getHeartBeatMessage() {
        WebSocketMessage vo = new WebSocketMessage() ;
        vo.type = WebSocketMessage.TYPE_HEARTBEAT ;
        vo.code = "" ;//心跳数据编码就是空字符串
        vo.content = DateTime.yyyy_MM_dd_HH_mm_ss() ;
        return JSON.toJSONString(vo) ;
    }
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/largeScreen/WebSocketServer.java
New file
@@ -0,0 +1,131 @@
package com.dy.pipIrrRemote.largeScreen;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import jakarta.websocket.*;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
/**
 * @Author: liurunyu
 * @Date: 2025/2/10 15:25
 * @Description å®¢æˆ·ç«¯ï¼ˆæµè§ˆå™¨ï¼‰æ¯å»ºç«‹ä¸€ä¸ªwebsocket连接,服务端就会创建一个WebSocketServer实例
 */
@Slf4j
@ServerEndpoint("/websocket/ls/{id}")
@Component
public class WebSocketServer {
    // é™æ€å˜é‡ï¼Œè®°å½•当前在线连接数
    private static int onlineCount = 0;
    // å­˜æ”¾æ¯ä¸ªå®¢æˆ·ç«¯å¯¹åº”çš„WebSocketServer对象
    private static ConcurrentHashMap<String, WebSocketServer> webSocketMap = new ConcurrentHashMap<>();
    // å®¢æˆ·ç«¯è¿žæŽ¥ä¼šè¯ï¼Œé€šè¿‡å®ƒç»™å®¢æˆ·ç«¯å‘送数据
    private Session session;
    // å®¢æˆ·ç«¯id
    private String id = "";
    /**
     * è¿žæŽ¥å»ºç«‹æˆåŠŸè°ƒç”¨çš„æ–¹æ³•
     * @param session websocket会话对象
     * @param id å®¢æˆ·ç«¯id
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("id") String id) {
        this.session = session;
        this.id = id;
        this.sendMessage(WebSocketHeartBeat.getHeartBeatMessage());
        if (webSocketMap.containsKey(id)) {
            webSocketMap.remove(id);
            webSocketMap.put(id, this);
        } else {
            webSocketMap.put(id, this);
            WebSocketServer.addOnlineCount();
        }
    }
    /**
     * è¿žæŽ¥å…³é—­è°ƒç”¨çš„æ–¹æ³•
     */
    @OnClose
    public void onClose() {
        if (webSocketMap.containsKey(id)) {
            webSocketMap.remove(id);
            //从set中删除
            WebSocketServer.subOnlineCount();
        }
        log.info("客户端:" + id + ",关闭了websocket");
    }
    /**
     * æ”¶åˆ°å®¢æˆ·ç«¯æ¶ˆæ¯åŽè°ƒç”¨çš„æ–¹æ³•
     * @param message å®¢æˆ·ç«¯å‘送过来的消息
     * @param session
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        log.info("客户端:" + id + ",websocket报文:" + message);
    }
    /**
     * ä¼šè¯å¼‚常
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("客户端:" + this.id + ",websocket会话异常,原因:" + error.getMessage());
    }
    /**
     * æœåŠ¡å™¨ä¸»åŠ¨æŽ¨é€æ¶ˆæ¯
     */
    public void sendMessage(String message) {
        try{
            this.session.getBasicRemote().sendText(message);
        }catch (Exception e){
            log.error("客户端:" + id + ",websocket网络发送数据异常", e);
        }
    }
    /**
     * æœåŠ¡å™¨ä¸»åŠ¨ç¾¤æŽ¨é€æ¶ˆæ¯
     */
    public static void sendAllMessage(String message) throws IOException {
        ConcurrentHashMap.KeySetView<String, WebSocketServer> ids = webSocketMap.keySet();
        for (String id : ids) {
            WebSocketServer webSocketServer = webSocketMap.get(id);
            webSocketServer.sendMessage(message);
        }
    }
    /**
     * æœåŠ¡å™¨æŒ‡å®šå®¢æˆ·ç«¯æŽ¨é€æ¶ˆæ¯
     */
    public static void sendOneMessage(String message, String id) throws IOException {
        if (message != null && message.length() != 0 && webSocketMap.containsKey(id)) {
            webSocketMap.get(id).sendMessage(message);
        } else {
            log.error("客户端" + id + ",不在线!");
        }
    }
    public static synchronized int getOnlineCount() {
        return onlineCount;
    }
    public static synchronized void addOnlineCount() {
        WebSocketServer.onlineCount++;
    }
    public static synchronized void subOnlineCount() {
        WebSocketServer.onlineCount--;
    }
}
pipIrr-platform/pipIrr-web/pom.xml
@@ -76,6 +76,11 @@
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>
        <!-- lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
pipIrr-platform/pom.xml
@@ -27,6 +27,9 @@
    </modules>
    <properties>
        <!-- ä¸Žjava.version配置在一起,设置编码集-->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>20</java.version>
        <tomcat.version>10.1.12</tomcat.version>
        <spring.boot.version>3.1.3</spring.boot.version>
@@ -66,7 +69,6 @@
                <scope>import</scope>
            </dependency>
            <!-- è¾“入参数据验证 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-validation</artifactId>
@@ -89,6 +91,13 @@
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-websocket</artifactId>
                <version>3.1.3</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- lombok -->
            <dependency>