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