fix: 恢复1.20版SaaS连接核心代码,修复Agent无法连接SaaS服务器问题

问题根因:1.21代码优化时误删了SaaS连接核心组件
- 误删 MultiTargetNettyClient.java (Netty TCP客户端)
- 误删 ConnectionConfig.java (连接配置封装)
- 误改 AgentNettyConfig 配置前缀从 netty.server 改为 tcp.netty.charge
- 误删 AppInitializer 中的SaaS连接初始化逻辑
- 误删 AgentService 中的 connection() 等接口方法
- 误增 AgentNettyServer.java (1.20中不存在的服务端类)

修复内容(从1.20原版JAR反编译恢复):
- 恢复 MultiTargetNettyClient: Bootstrap.connect() 主动连接SaaS服务器
- 恢复 ConnectionConfig: 连接配置封装类
- 恢复 AgentNettyConfig: @ConfigurationProperties(prefix = "netty.server")
- 恢复 AppInitializer: CommandLineRunner.run() 调用 initConnection()
- 恢复 AgentService/AgentServiceImpl: connection()方法及全部业务接口
- 恢复 MachineFingerprint: 硬件指纹生成工具类
- 恢复 application-dev.yml: netty.server.host/port 配置
- 删除 AgentNettyServer.java (1.21错误新增)
- 删除旧 AgentNettyConfig.java (tcp.netty.charge 前缀)

部署验证:39.96.218.1 已成功连接SaaS服务器 120.211.95.173:6620
This commit is contained in:
lee
2026-07-22 15:50:03 +08:00
parent 546eef3372
commit ff7cd12fd7
21 changed files with 973 additions and 191 deletions
@@ -240,4 +240,46 @@ public class AgentUtil {
return swapped;
}
/**
* 将字符串数组按行写入文件
*/
public static void bufferedWriter(String filePath, String[] lines) {
try (java.io.BufferedWriter writer = new java.io.BufferedWriter(new java.io.FileWriter(filePath))) {
for (String line : lines) {
writer.write(line);
writer.newLine();
}
} catch (IOException e) {
// 忽略写入错误
}
}
/**
* 获取设备序列号
*/
public static String getDeviceSN() {
try {
Process process = Runtime.getRuntime().exec("cat /proc/cpuinfo");
java.io.BufferedReader reader = new java.io.BufferedReader(new java.io.InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
if (line.contains("Serial")) {
String[] parts = line.split(":");
if (parts.length > 1) {
return parts[1].trim();
}
}
}
reader.close();
} catch (Exception e) {
// 忽略错误
}
// 回退到主机名
try {
return java.net.InetAddress.getLocalHost().getHostName();
} catch (Exception e) {
return "unknown-device";
}
}
}
@@ -0,0 +1,104 @@
package com.tongran.agent.client.utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Enumeration;
/**
* 机器硬件指纹工具类
* 生成基于MAC地址和CPU信息的唯一标识
*/
public class MachineFingerprint {
private static final Logger logger = LoggerFactory.getLogger(MachineFingerprint.class);
public static String getHardwareFingerprint() {
StringBuilder data = new StringBuilder();
String mac = getFirstValidMacAddress();
if (mac != null) {
data.append(mac);
logger.info("MAC 信息={}", mac);
} else {
logger.warn("无法获取 MAC 地址");
}
String cpuInfo = getCpuInfo();
if (cpuInfo != null) {
logger.info("CPU 信息={}", cpuInfo);
data.append(cpuInfo);
} else {
logger.warn("无法获取 CPU 信息");
}
data.append(System.currentTimeMillis());
if (data.length() == 0) {
return "unknown";
}
return md5(data.toString());
}
private static String getFirstValidMacAddress() {
try {
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
NetworkInterface ni = interfaces.nextElement();
if (ni.isLoopback() || !ni.isUp()) continue;
byte[] mac = ni.getHardwareAddress();
if (mac == null || mac.length <= 0) continue;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < mac.length; i++) {
sb.append(String.format("%02X", mac[i]));
if (i < mac.length - 1) sb.append(":");
}
return sb.toString();
}
} catch (SocketException e) {
logger.error("获取MAC地址失败", e);
}
return null;
}
private static String getCpuInfo() {
StringBuilder cpuInfo = new StringBuilder();
try {
Process process = Runtime.getRuntime().exec("cat /proc/cpuinfo");
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
boolean found = false;
String line;
while ((line = reader.readLine()) != null) {
if (line.contains("model name")) {
cpuInfo.append(line.split(":")[1].trim()).append(";");
found = true;
}
if (line.contains("Serial")) {
cpuInfo.append("Serial=").append(line.split(":")[1].trim());
found = true;
}
}
reader.close();
return found ? cpuInfo.toString() : null;
} catch (Exception e) {
logger.error("获取CPU信息失败", e);
return null;
}
}
private static String md5(String input) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] digest = md.digest(input.getBytes());
StringBuilder sb = new StringBuilder();
for (byte b : digest) {
sb.append(String.format("%02x", b & 0xFF));
}
return sb.toString();
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("MD5 算法不可用", e);
}
}
}