chenyc
2025-12-09 545c24c6a711d71b65f3d4e8122fee3837fb1edc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
const net = require('net');
const FreseniusXMLParser = require('./xmlParser');
const ParameterParser = require('./parser');
const MQTTClient = require('./mqttClient');
const AliyunIoTClient = require('./aliyunClient');
const appLogger = require('./loggerConfig');
const config = require('./config.json');
 
let clientCount = 0;  // 全局客户端计数
const deviceMQTTClients = new Map();  // 存储每个设备的MQTT客户端
const deviceAliyunClients = new Map();  // 存储每个设备的阿里云客户端
 
// 获取服务器配置
const serverConfig = config.server || { port: 700, address: '0.0.0.0' };
 
// 创建 TCP 服务器
const server = net.createServer((socket) => {
  // 为每个客户端创建独立的解析器
  const clientParser = new FreseniusXMLParser();
  clientCount++;
  const clientId = clientCount;
 
  appLogger.logTcpConnection(socket.remoteAddress, socket.remotePort, clientId);
 
  socket.on('data', (data) => {
    const ip = socket.remoteAddress;
    // 记录原始 TCP 消息(在解析前)
    appLogger.logRawTcpMessage(clientId, data, null, ip);
    
    const records = clientParser.parseData(data);
    
    if (records.length > 0) {
      const paramDict = ParameterParser.getParameterDict();
      records.forEach((record) => {
        // 获取设备序号
        const deviceSerialNumber = record.keyData.serialNumber;
        
        // 记录原始 TCP 消息到设备特定的日志(这样可以将原始消息与设备关联)
        appLogger.logRawTcpMessage(clientId, data, deviceSerialNumber, ip);
        
        // 记录数据接收和解析
        appLogger.logDataReceived(clientId, deviceSerialNumber, data.length);
        appLogger.logDataParsed(clientId, deviceSerialNumber, 1, record.parameters);
        appLogger.logDeviceRegistration(deviceSerialNumber, socket.remoteAddress);
        
        // 如果有状态事件,记录事件
        if (record.stateEvent) {
          appLogger.logStateEvent(deviceSerialNumber, record.stateEvent.type, record.stateEvent.description);
        }
        
        // ========== MQTT 上传 ==========
        // 为该设备创建或获取MQTT客户端
        if (!deviceMQTTClients.has(deviceSerialNumber)) {
          const mqttClient = new MQTTClient(deviceSerialNumber);
          appLogger.logMqttConnecting(deviceSerialNumber);
          mqttClient.connect().then(() => {
            appLogger.logMqttConnected(deviceSerialNumber, 'MQTT Broker');
            console.log(`✓ 设备 ${deviceSerialNumber} 的MQTT客户端已准备就绪\n`);
          }).catch((err) => {
            appLogger.logMqttConnectionError(deviceSerialNumber, err);
            console.error(`✗ 设备 ${deviceSerialNumber} 的MQTT连接失败:`, err.message, '\n');
          });
          deviceMQTTClients.set(deviceSerialNumber, mqttClient);
        }
        
        // 上传关键医疗数据到MQTT
        const mqttClient = deviceMQTTClients.get(deviceSerialNumber);
        if (mqttClient) {
          const keyDataStr = JSON.stringify(record.keyData);
          appLogger.logMqttPublishing(deviceSerialNumber, `device/${deviceSerialNumber}`, keyDataStr.length);
          mqttClient.publishKeyData(record.keyData, socket.remoteAddress);
          
          // 如果有状态事件,也上传事件
          if (record.stateEvent) {
            appLogger.logMqttPublishing(deviceSerialNumber, `device/${deviceSerialNumber}/event`, JSON.stringify(record.stateEvent).length);
            mqttClient.publishEvent(record.stateEvent);
          }
        }
        
        // ========== 阿里云 IoT 上传 ==========
        // 为该设备创建或获取阿里云客户端
        let aliyunClient = deviceAliyunClients.get(deviceSerialNumber);
        
        // 如果客户端不存在,或者存在但未成功连接,则创建或重试连接
        if (!aliyunClient || !aliyunClient.isConnected) {
          if (!aliyunClient) {
            // 首次创建客户端
            aliyunClient = new AliyunIoTClient(deviceSerialNumber);
            deviceAliyunClients.set(deviceSerialNumber, aliyunClient);
            appLogger.logAliyunConnecting(deviceSerialNumber);
            console.log(`🔄 为设备 ${deviceSerialNumber} 创建阿里云 IoT 客户端...\n`);
          } else {
            // 之前连接失败,重试连接
            appLogger.logInfo(`重新尝试连接阿里云 IoT`, {
              module: 'aliyun',
              device: deviceSerialNumber,
              timestamp: new Date().toISOString()
            });
            console.log(`🔄 重新尝试连接阿里云 IoT [设备: ${deviceSerialNumber}]...\n`);
          }
          
          // 异步连接(支持通过 API 获取三元组)
          aliyunClient.connect().then(() => {
            appLogger.logAliyunConnected(deviceSerialNumber, record.keyData.deviceModel);
            console.log(`✓ 设备 ${deviceSerialNumber} 的阿里云 IoT 客户端已准备就绪\n`);
            
            // 连接成功后上传数据
            const keyDataStr = JSON.stringify(record.keyData);
            appLogger.logAliyunPublishing(deviceSerialNumber, 'properties', keyDataStr.length);
            aliyunClient.publishProperties(record.keyData);
            
            if (record.stateEvent) {
              appLogger.logAliyunPublishing(deviceSerialNumber, 'event', JSON.stringify(record.stateEvent).length);
              aliyunClient.publishEvent(record.stateEvent);
            }
          }).catch((err) => {
            appLogger.logAliyunConnectionError(deviceSerialNumber, err);
            console.error(`✗ 设备 ${deviceSerialNumber} 的阿里云 IoT 连接失败:`, err.message, '\n');
          });
        } else {
          // 已连接的设备直接上传数据
          if (aliyunClient && aliyunClient.isConnected) {
            const keyDataStr = JSON.stringify(record.keyData);
            appLogger.logAliyunPublishing(deviceSerialNumber, 'properties', keyDataStr.length);
            aliyunClient.publishProperties(record.keyData);
            
            if (record.stateEvent) {
              appLogger.logAliyunPublishing(deviceSerialNumber, 'event', JSON.stringify(record.stateEvent).length);
              aliyunClient.publishEvent(record.stateEvent);
            }
          }
        }
      });
    }
    
    socket.write('ACK');
  });
 
  socket.on('end', () => {
    appLogger.logTcpDisconnection(clientId, clientParser.getRecordCount(), null, socket.remoteAddress);
  });
 
  socket.on('error', (err) => {
    appLogger.logTcpError(clientId, err, null, socket.remoteAddress);
  });
});
 
server.listen(serverConfig.port, serverConfig.address, () => {
  appLogger.logInfo('🚀 TCP 服务器启动成功', { 
    port: serverConfig.port, 
    address: serverConfig.address,
    timestamp: new Date().toISOString()
  });
});
 
server.on('error', (err) => {
  if (err.code === 'EACCES') {
    appLogger.logError('端口权限错误', err, { port: serverConfig.port });
  } else {
    appLogger.logError('服务器错误', err, {});
  }
});