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, {}); } });