From 8aa9e121554b84735c8ec6139bd095ea3acb05e7 Mon Sep 17 00:00:00 2001
From: liusuyi <1951119284@qq.com>
Date: Tue, 14 Oct 2025 16:10:49 +0800
Subject: [PATCH] 更改六合边缘服务器动态连接

---
 ard-work/src/main/java/com/ard/work/component/netty/TyTcpClientManager.java |   97 +++++++++++++++++++++++++++++++++---------------
 1 files changed, 66 insertions(+), 31 deletions(-)

diff --git a/ard-work/src/main/java/com/ard/work/component/netty/TyTcpClientManager.java b/ard-work/src/main/java/com/ard/work/component/netty/TyTcpClientManager.java
index c087b4a..7fbf709 100644
--- a/ard-work/src/main/java/com/ard/work/component/netty/TyTcpClientManager.java
+++ b/ard-work/src/main/java/com/ard/work/component/netty/TyTcpClientManager.java
@@ -1,6 +1,7 @@
 package com.ard.work.component.netty;
 
 import com.ard.work.component.netty.command.BaseCmd;
+import com.ard.work.component.netty.command.register.HeartbeatCmd;
 import com.ard.work.component.netty.handler.ClientHandler;
 import com.ard.work.component.netty.handler.MessageProtocolDecoder;
 import com.ard.work.component.netty.handler.MessageProtocolEncoder;
@@ -15,6 +16,7 @@
 import io.netty.handler.timeout.IdleStateHandler;
 import io.netty.util.AttributeKey;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
 import javax.annotation.PostConstruct;
 import javax.annotation.Resource;
@@ -61,39 +63,28 @@
         return bootstrap;
     }
 
-    /**
-     * 初始化与天宇服务器的连接
-     */
-    public void initConnection(String serverId, String host, Integer port) {
-        String key = host + ":" + port;
-        log.info("初始化连接边缘服务器 [{}] ({})", serverId, key);
+    /** 新增或重连服务器 */
+    public void connectServer(ArdServerInfo serverInfo) {
+        String serverId = serverInfo.getId();
+        String host = serverInfo.getHost();
+        Integer port = serverInfo.getTcpPort();
 
-        // 如果存在旧连接则关闭
-        if (channels.containsKey(serverId)) {
-            TcpClientSession oldSession = channels.get(serverId);
-            if (oldSession != null && oldSession.getChannelFuture() != null) {
-                oldSession.getChannelFuture().channel().close();
-            }
-        }
+        // 如果已有旧连接,先断开
+        disconnectServer(serverId);
 
-        // 异步连接 TCP 服务端
         Bootstrap bootstrap = getBootstrap();
-        ChannelFuture future = bootstrap.connect(host, port).addListener((ChannelFuture futureListener) -> {
-            if (futureListener.isSuccess()) {
-                log.info("✅ 边缘服务器 [{}] 连接成功 ({})", serverId, key);
-                Channel channel = futureListener.channel();
-                // 绑定 serverId 到 channel
+        ChannelFuture future = bootstrap.connect(host, port).addListener((ChannelFuture f) -> {
+            if (f.isSuccess()) {
+                log.info("✅ 服务器 [{}] 连接成功", serverId);
+                Channel channel = f.channel();
                 channel.attr(AttributeKey.valueOf("serverId")).set(serverId);
-                TyTcpServerCache.putTcpServerCache(key, true);
+                TyTcpServerCache.putTcpServerCache(serverId, true);
             } else {
-                log.warn("❌ 边缘服务器 [{}] 连接失败 ({}),10 秒后重试", serverId, key);
-                TyTcpServerCache.putTcpServerCache(key, false);
-                final EventLoop eventLoop = futureListener.channel().eventLoop();
-                eventLoop.schedule(() -> initConnection(serverId, host, port), 10, TimeUnit.SECONDS);
+                log.warn("❌ 服务器 [{}] 连接失败", serverId);
+                TyTcpServerCache.putTcpServerCache(serverId, false);
             }
         });
 
-        // 存入连接缓存
         TcpClientSession session = TcpClientSession.builder()
                 .ClientId("TY_" + serverId)
                 .channelFuture(future)
@@ -106,6 +97,16 @@
         channels.put(serverId, session);
     }
 
+    /** 断开服务器连接 */
+    public void disconnectServer(String serverId) {
+        TcpClientSession session = channels.remove(serverId);
+        if (session != null && session.getChannelFuture() != null) {
+            session.getChannelFuture().channel().close();
+            log.info("断开服务器 [{}] 连接", serverId);
+        }
+        TyTcpServerCache.removeTcpServerCache(serverId);
+    }
+
     /**
      * 向指定边缘服务器发送消息
      */
@@ -113,23 +114,23 @@
         try {
             TcpClientSession session = channels.get(serverId);
             if (session == null) {
-                log.error("未找到天宇服务器 [{}] 的连接", serverId);
+                log.error("未找到六合服务器 [{}] 的连接", serverId);
                 return;
             }
 
             ChannelFuture future = session.getChannelFuture();
             if (future == null || !future.channel().isActive()) {
-                log.warn("天宇服务器 [{}] 连接未激活,无法发送消息", serverId);
+                log.warn("六合服务器 [{}] 连接未激活,无法发送消息", serverId);
                 return;
             }
 
             InetSocketAddress remote = (InetSocketAddress) future.channel().remoteAddress();
             future.channel().writeAndFlush(msg);
-            log.debug("→ 向天宇服务器 [{}] ({}:{}) 发送消息,命令码:0x{}",
+            log.debug("→ 向六合服务器 [{}] ({}:{}) 发送消息,命令码:0x{}",
                     serverId, remote.getHostString(), remote.getPort(),
                     String.format("%02X", msg.getCmdCode() & 0xFF));
         } catch (Exception e) {
-            log.error("发送消息到天宇服务器 [{}] 异常:{}", serverId, e.getMessage());
+            log.error("发送消息到六合服务器 [{}] 异常:{}", serverId, e.getMessage());
         }
     }
 
@@ -137,7 +138,7 @@
      * 启动时从数据库加载所有边缘服务器并建立 TCP 连接
      */
     @PostConstruct
-    public void createAllTyConnections() {
+    public void initConnectServers() {
         try {
             var serverList = ardServerService.selectArdServerManagementList(new ArdServerInfo()); // ← 从数据库查询所有服务器配置
             if (serverList == null || serverList.isEmpty()) {
@@ -146,7 +147,7 @@
             }
 
             for (ArdServerInfo serverInfo : serverList) {
-                initConnection(serverInfo.getId(), serverInfo.getHost(), serverInfo.getTcpPort());
+                connectServer(serverInfo);
             }
 
             log.info("共初始化 {} 个边缘服务器连接", serverList.size());
@@ -154,4 +155,38 @@
             log.error("创建边缘服务器连接异常:{}", e.getMessage(), e);
         }
     }
+
+    @Scheduled(fixedDelay = 10000) // 每 10 秒检查一次
+    public void reconnectFailedServers() {
+        TyTcpServerCache.getTcpServerCacheMap().forEach((key, state) -> {
+            if (Boolean.FALSE.equals(state)) { // 连接失败的服务器
+                ArdServerInfo serverInfo = ardServerService.selectArdServerManagementById(key);
+                if (serverInfo != null) {
+                    connectServer(serverInfo);
+                }
+            }
+        });
+    }
+
+    /**
+     * 定时向所有已连接的六合服务器发送心跳
+     */
+    @Scheduled(fixedRate = 5000) // 每5秒执行一次
+    public void sendHeartBeat() {
+        long timestamp = System.currentTimeMillis();
+        channels.values().stream()
+                .filter(session -> {
+                    ChannelFuture future = session.getChannelFuture();
+                    // 只保留活跃连接
+                    return future != null && future.channel().isActive();
+                })
+                .forEach(session -> {
+                    HeartbeatCmd heartbeat = new HeartbeatCmd(timestamp);
+                    ChannelFuture future = session.getChannelFuture();
+                    future.channel().writeAndFlush(heartbeat);
+                    log.info("→ 向边缘服务器 [{}] ({}:{}) 发送心跳,时间戳={}",
+                            session.getServerId(), session.getHost(), session.getPort(), timestamp);
+                });
+    }
+
 }

--
Gitblit v1.9.3