根据卓岚的通讯文件做的透析机通讯
chenyc
2025-12-09 58b579ac16073398089ed095788072d3fc17cc62
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
// aliyun-iot.js
const IotDevice = require('aliyun-iot-device-sdk');
const logger = require('./logger');
 
// 固定设备信息
const PRODUCT_KEY = 'k08fz9HAzxl';
const DEVICE_SECRET = '06f039246b5affc83b567baa8bb5b937';
 
// 存储设备实例(长连接复用)
const devices = new Map();
 
/**
 * 获取或创建设备实例(长连接)
 * @param {string} deviceId
 * @return {Object|null} 设备实例 或 null(创建失败)
 */
function getOrCreateDevice(deviceId) {
    if (!deviceId || typeof deviceId !== 'string') {
        logger.error('无效的 deviceId', { deviceId });
        return null;
    }
 
    const existingDevice = devices.get(deviceId);
    if (existingDevice) {
        return existingDevice;
    }
 
    try {
        const device = IotDevice.device({
            productKey: PRODUCT_KEY,
            deviceName: deviceId,
            deviceSecret: DEVICE_SECRET,
            host: `${PRODUCT_KEY}.iot-as-mqtt.cn-shanghai.aliyuncs.com`,
            port: 1883,
            keepalive: 60,
            clean: true,
            reconnectPeriod: 5000 // 自动重连间隔
        });
 
        device.on('connect', () => {
            logger.info(`✅ 设备 ${deviceId} 已连接到阿里云 IoT`);
        });
 
        device.on('reconnect', () => {
            logger.warn(`🔁 设备 ${deviceId} 正在重连...`);
        });
 
        device.on('error', (err) => {
            logger.error(`❌ 设备 ${deviceId} 发生错误`, {
                错误: err.message,
                堆栈: err.stack
            });
        });
 
        device.on('offline', () => {
            logger.warn(`⚠️ 设备 ${deviceId} 已离线`);
        });
 
        // 缓存实例
        devices.set(deviceId, device);
 
        return device;
 
    } catch (err) {
        logger.error('创建设备实例失败', {
            错误: err.message,
            堆栈: err.stack,
            deviceId
        });
        return null;
    }
}
 
/**
 * 发送数据到阿里云 IoT(高频上报,长连接)
 * @param {string} deviceId
 * @param {Object} data
 */
function sendDataToAliyun(deviceId, data) {
    // 参数校验
    if (!deviceId || typeof deviceId !== 'string' || !data || typeof data !== 'object') {
        logger.error('sendDataToAliyun 参数错误', { deviceId, data: typeof data });
        return;
    }
 
    let device;
    try {
        device = getOrCreateDevice(deviceId);
        if (!device) {
            logger.error('无法创建设备实例', { deviceId });
            return;
        }
 
        // 如果未连接,不阻塞,直接返回(可选:记录日志)
        if (!device.connected) {
            logger.warn(`设备 ${deviceId} 当前未连接,跳过发送`);
            return;
        }
 
        // 发送数据
        device.postProps(data, (res) => {
            console.log('Aliyun IoT postProps 回调:', res);
            if (res?.message === 'success') {
                // 成功:无需日志(太频繁),可注释
                logger.debug(`📡 数据已发送`, { deviceId });
            } else {
                const errorMsg = res?.message || '未知错误';
                logger.error(`❌ 发送失败`, { deviceId, 错误: errorMsg, data });
            }
        });
 
    } catch (err) {
        logger.error('sendDataToAliyun 执行异常', {
            错误: err.message,
            堆栈: err.stack,
            deviceId,
            data
        });
    }
}
 
/**
 * 关闭所有设备连接(用于进程退出)
 */
function closeAllConnections() {
    devices.forEach((device, id) => {
        try {
            device.end();
            logger.info(`已关闭设备连接: ${id}`);
        } catch (err) {
            logger.error(`关闭设备 ${id} 失败`, { 错误: err.message });
        }
    });
    devices.clear();
}
 
// 优雅退出
process.on('SIGINT', closeAllConnections);
process.on('SIGTERM', closeAllConnections);
 
module.exports = {
    sendDataToAliyun,
    closeAllConnections // 可选导出,用于主程序调用
};