From 55c8181bbe4c198f9bda5520ea0d8ba148933f9e Mon Sep 17 00:00:00 2001
From: chenyc <501753378@qq.com>
Date: 星期五, 16 一月 2026 10:34:53 +0800
Subject: [PATCH] gx重试指令间隔

---
 index.js |  147 ++++++++++++++++++++++++++++++++++--------------
 1 files changed, 104 insertions(+), 43 deletions(-)

diff --git a/index.js b/index.js
index 7a64ad4..826b343 100644
--- a/index.js
+++ b/index.js
@@ -1,10 +1,40 @@
+
+
+// ✅ 正确写法(适用于 pkg 打包环境)
+const fs = require('fs');
+const path = require('path');
+
+
+// 获取 exe 所在目录(兼容 pkg 打包后的 __dirname)
+const appPath = process.pkg ? path.dirname(process.execPath) : __dirname;
+const mqttConfigPath = path.join(appPath, 'mqtt.json');
+const aliyunConfigPath = path.join(appPath, 'aliyun.json');
+const httpConfigPath = path.join(appPath, 'httpConfig.json');
+const homeConfigPath = path.join(appPath, 'homeConfig.json');
+
+const mqttConfig = JSON.parse(fs.readFileSync(mqttConfigPath, 'utf8'));
+const aliyunConfig = JSON.parse(fs.readFileSync(aliyunConfigPath, 'utf8'));
+const httpConfig = JSON.parse(fs.readFileSync(httpConfigPath, 'utf8'));
+const homeConfig = JSON.parse(fs.readFileSync(homeConfigPath, 'utf8'));
+
+
+console.log(aliyunConfig)
+
+
+
+const { initMqtt, publishMessage } = require('./mqttClient');
+
 const net = require('net');
 const logger = require('./logger');
 const EventEmitter = require('events');
 const aliyunIot = require('aliyun-iot-device-sdk');
 const { getAliyunDeviceSecret } = require('./api');
 const toModel = require('./Strholp');
-const { publishMessage } = require('./mqttClient');
+const dataCache = require('./dataCache');
+const HttpServer = require('./httpServer');
+
+// 初始化 MQTT(独立于阿里云)
+initMqtt(mqttConfig);
 
 // ========== 自定义错误类(可选)==========
 class CustomError extends Error {
@@ -16,7 +46,7 @@
 
 // ========== 常量配置 ==========
 const MAX_BUFFER_SIZE = 500;      // 缓冲区最大长度
-const RETRY_INTERVAL_MS = 10000;  // 重试间隔 10s
+const RETRY_INTERVAL_MS = 30000;  // 重试间隔 30s
 const KEEP_ALIVE_INTERVAL_MS = 60000; // 保活间隔 60s
 const DEVICE_TIMEOUT_MS = 120000; // 设备无响应超时 2分钟
 
@@ -39,7 +69,12 @@
     }
 
     handleDevice(socket) {
-        const deviceId = socket.remoteAddress + ':' + socket.remotePort;
+        // 处理 IPv6 映射 IPv4 地址 (::ffff:127.0.0.1 -> 127.0.0.1)
+        let remoteAddress = socket.remoteAddress;
+        if (remoteAddress.startsWith('::ffff:')) {
+            remoteAddress = remoteAddress.slice(7); // 移除 ::ffff: 前缀
+        }
+        const deviceId = remoteAddress + ':' + socket.remotePort;
         logger.info(`建立新连接: ${deviceId}`);
 
         const deviceInfo = {
@@ -85,7 +120,7 @@
                 const message = buffer.substring(startIdx, endIdx).trim();
                 buffer = buffer.substring(endIdx + 2); // 移除已处理部分(含 \r\n)
 
-                logger.info(`${deviceId} 接收到完整消息: ${message}`);
+                logger.info(`${deviceId} 接收到完整消息: ${randomLetters(20)}${message}${randomLetters(20)}`);
                 this.handleData(deviceId, message);
             }
         });
@@ -110,7 +145,7 @@
             if (deviceInfo.status === 'pending' || deviceInfo.status === 'invalid') {
                 // 握手阶段:在 'K' 和 'K0000' 之间切换(你的原始逻辑)
                 deviceInfo.lastSignal = deviceInfo.lastSignal === 'K' ? 'K0000' : 'K';
-                logger.info(`重试发送 '${deviceInfo.lastSignal}' 给设备 ${deviceId}`);
+                logger.info(`重试发送 '${randomLetters(10)}${deviceInfo.lastSignal==='K'?'a':'b'}${randomLetters(10)}' 给设备 ${deviceId}`);
                 this.sendKeepAliveToDevice(deviceId);
             }
         }, RETRY_INTERVAL_MS);
@@ -149,7 +184,7 @@
 
         try {
             deviceInfo.socket.write(`${deviceInfo.lastSignal}\r\n`);
-            logger.info(`发送信号 '${deviceInfo.lastSignal}' 给设备 ${deviceId}`);
+            logger.info(`发送信号 '${randomLetters(10)}${deviceInfo.lastSignal==='K'?'a':'b'}${randomLetters(10)}' 给设备 ${deviceId}`);
         } catch (err) {
             logger.error(`发送信号失败 ${deviceId}:`, err.message);
             this.removeDevice(deviceId);
@@ -159,33 +194,58 @@
     async handleData(deviceId, message) {
         const deviceInfo = this.devices.get(deviceId);
         if (!deviceInfo) return;
-
         deviceInfo.lastAck = Date.now();
 
         try {
-            const masData = toModel(message);
+            const ipAddress = deviceId
+            const masData = toModel(message, ipAddress);
             deviceInfo.iotDeviceNo = masData.n;
             deviceInfo.masData = masData;
+            
+            
+            // ✅【新增】缓存数据到内存(按设备序号)
+            dataCache.setDeviceData(masData.n, masData);
+            
+            // ✅【核心改动】收到数据立即发 MQTT(不管阿里云)
+            if (mqttConfig.enabled) {
+                const topic = `${mqttConfig.defaultTopicPrefix}/${masData.n}`;
+                const payload = JSON.stringify({
+                    ...masData,
+                    deviceId: deviceId,
+                    timestamp: new Date().toISOString()
+                });
+                publishMessage(topic, payload);
+                logger.info(`📡 已通过 MQTT 发送数据到 ${topic}`);
+            }
 
-            if (deviceInfo.status !== 'valid') {
-                deviceInfo.status = 'valid';
-                this.emit('validResponse', deviceId);
-                logger.info(`${deviceId} 首次有效响应,停止重试`);
-                this.stopRetryMechanism(deviceId);
-                // 成功后固定使用 'K0000' 保活(建议)
-                this.startKeepAlive(deviceId, deviceInfo.lastSignal);
-                await this.registerDevice(deviceId);
+            // 【可选】仅当阿里云启用时才注册并上报
+            if (aliyunConfig.enabled) {
+                if (deviceInfo.status !== 'valid') {
+                    logger.info(`${deviceId} 阿里云设备状态变为有效`);
+                    deviceInfo.status = 'valid';
+                    this.stopRetryMechanism(deviceId);
+                    logger.info(`${deviceId} 停止重试机制`);
+                    this.startKeepAlive(deviceId, deviceInfo.lastSignal);
+                    logger.info(`${deviceId} 启动保持连接机制`);
+                    await this.registerAliyunDevice(deviceId); // 改名避免混淆
+                } else {
+                    this.postPropsToAliyun(deviceId);
+                }
             } else {
-                logger.info(`${deviceId} 已注册,直接上报数据到阿里云`);
-                this.postPropsToDevice(deviceId);
-                // this.onDeviceDataReceived(deviceId, masData);
+                // 阿里云未启用,但已通过 MQTT 发送,无需其他操作
+                if (deviceInfo.status !== 'valid') {
+                    deviceInfo.status = 'valid';
+                    this.stopRetryMechanism(deviceId);
+                    this.startKeepAlive(deviceId, deviceInfo.lastSignal);
+                    logger.info(`${deviceId} 已完成握手(阿里云未启用)`);
+                }
             }
         } catch (err) {
             logger.error(`${deviceId} 处理消息出错:`, err.message);
         }
     }
 
-    async registerDevice(deviceId) {
+    async registerAliyunDevice(deviceId) {
         const deviceInfo = this.devices.get(deviceId);
         if (!deviceInfo || deviceInfo.iotDevice) return;
 
@@ -193,7 +253,7 @@
             logger.info(`${deviceId} 请求三元组,设备号: ${deviceInfo.iotDeviceNo}`);
             const { data } = await getDeviceSYZ(deviceInfo.iotDeviceNo);
             logger.info(`${deviceId} 三元组返回: ${JSON.stringify(data)}`);
-            const model=data.data
+            const model = data.data
             if (model?.productKey && model?.deviceName && model?.deviceSecret) {
                 deviceInfo.iotDevice = aliyunIot.device({
                     ProductKey: model.productKey,
@@ -214,33 +274,18 @@
         }
     }
 
-    postPropsToDevice(deviceId) {
+    postPropsToAliyun(deviceId) {
         const deviceInfo = this.devices.get(deviceId);
         if (!deviceInfo?.iotDevice || !deviceInfo.masData) return;
-
+        logger.info(`${deviceId} 阿里云上报属性: ${JSON.stringify(deviceInfo.masData)}`);
         const props = deviceInfo.masData;
         deviceInfo.iotDevice.postProps(props, (res) => {
             if (res?.message === 'success') {
-                logger.info(`${deviceId} 上报属性成功`);
+                logger.info(`${deviceId} 阿里云上报属性成功`);
             } else {
-                logger.error(`${deviceId} 上报属性失败:`, res?.message || 'unknown');
+                logger.error(`${deviceId} 阿里云上报属性失败:`, res?.message || 'unknown');
             }
         });
-    }
-
-    onDeviceDataReceived(deviceId, data) {
-        const topic = `touxiji/${data.n}`;
-        const payload = JSON.stringify({
-            ...data,
-            timestamp: new Date().toISOString()
-        });
-
-        try {
-            logger.info(`发布 MQTT 消息到主题 ${topic}: ${payload}`);
-            publishMessage(topic, payload);
-        } catch (error) {
-            logger.error(`MQTT 发布失败 ${topic}:`, error.message);
-        }
     }
 
     removeDevice(deviceId) {
@@ -273,6 +318,17 @@
         throw new CustomError("获取三元组失败", err);
     }
 }
+// 生成随机字母字符串
+function randomLetters(length) {
+  const chars = 'abcdefghijklmnopqrstuvwxyz';
+  let result = '';
+  for (let i = 0; i < length; i++) {
+    result += chars.charAt(Math.floor(Math.random() * chars.length));
+  }
+  return result;
+}
+
+
 
 // ========== 启动服务器 ==========
 const manager = new DeviceManager(); // ✅ 单例!
@@ -289,7 +345,12 @@
     manager.handleDevice(socket);
 });
 
-const PORT = process.env.PORT || 10961;
+const PORT =  homeConfig.socketPort || 10961;
 server.listen(PORT, () => {
-    logger.info(`Socket 服务已启动,监听端口: ${PORT}`);
-});
\ No newline at end of file
+    logger.info(`Socket 服务已启动,监听超级端口: ${PORT}`);
+});
+
+// ========== 启动 HTTP 服务 ==========
+const HTTP_PORT = process.env.HTTP_PORT || httpConfig.port || 8080;
+const httpServer = new HttpServer(HTTP_PORT, httpConfig);
+httpServer.start();
\ No newline at end of file

--
Gitblit v1.8.0