node-red边缘低代码开发网关基于node-red和influxdb断点继传功能(1)

12 阅读6分钟

该方案以时间戳为进度标记、InfluxDB 为本地缓存、TCP 为传输协议,实现网络中断后的断点续传,适用于传感器数据(如湿度数据)等高频小体量数据的可靠传输。以下是分阶段的详细流程拆解和流程图:

一、系统初始化阶段:环境与基准配置

初始化是断点续传的基础,核心目标是创建数据存储载体、初始化进度基准(时间戳),确保后续传输有 “起点” 可追溯。

1.InfluxDB 数据库创建

(1)触发节点: 通过inject节点发送初始化信号,触发 “创建一个数据库” 函数节点。

(2)执行逻辑: 函数节点通过 InfluxDB SQL 语句CREATE DATABASE mydb,在本地 InfluxDB 服务(地址:127.0.0.1:8086)中创建名为mydb的数据库,用于存储待补传数据(表:myDatas)与传输进度。

2.时间戳基准初始化

(1)首次启动场景: 通过catch节点捕获初始状态,触发 “时间初始化” 函数节点,生成当前系统时间戳(Date.now()),并通过 “写时间” 文件节点存入本地文件dataTime,同时将时间戳存入 Node-RED 全局变量global.time,作为后续传输的进度基准。

(2)重启恢复场景:系统重启时,inject节点触发 “读时间” 文件节点,读取本地dataTime文件中的历史时间戳,通过 “存储补传时间” 函数节点更新全局变量global.time,确保从上次断点继续。

二、正常传输阶段:实时数据发送与进度同步

正常网络状态下,系统完成 “数据采集 - 封装 - 发送 - 进度记录” 的闭环,确保每批数据的传输进度可追溯。

1.传感器数据采集

(1)触发周期: inject节点以 1 秒为周期发送采集信号,触发 “modbus-getter” 节点。

(2)数据来源: 通过 Modbus 协议从设备(地址:192.168.1.105:502)读取湿度数据(寄存器地址 0,数据类型 Holding Register),输出格式为数组。

2.网络状态判断与数据分流

(1)状态检测: 采集到的湿度数据传入 “判断网络状态处理” 函数节点,该节点通过读取全局变量global.conncetFlag(TCP 连接状态标记,true为连接成功,false为失败)判断网络状态,数据封装。

(2)连接成功(conncetFlag=true): 生成包含湿度(humidity)、当前时间戳(uptime=Date.now())、状态标记(status=1,代表 “实时数据”)的 JSON 对象,如{"humidity":65,"uptime":1690000000000,"status":1},并转为字符串格式作为 TCP 发送 payload。

(3)连接失败(conncetFlag=false): 仅保留湿度数据({"hum":65}),不添加时间戳与状态标记,待后续补传。

三、网络异常阶段:断点捕获与数据缓存

当 TCP 连接中断时,系统立即暂停无效传输,将未发送数据缓存至 InfluxDB,避免数据丢失。

1.TCP 连接状态监控

(1)状态捕获: “status” 节点实时监控 “tcp out” 节点的连接状态,若检测到 “status.text” 中不含 “status.connected”(代表连接中断),则触发 “switch” 节点)的 “else” 分支。

(2)状态标记更新: “连接失败” 函数节点,将全局变量global.conncetFlag设为false,并发送msg.reset=true信号至 “trigger” 节点,暂停后续补传触发逻辑。

2.待补传数据缓存

(1)缓存逻辑: “判断网络状态处理” 节点检测到conncetFlag=false时,将未发送的湿度数据通过 “InfluxDB out” 节点写入mydb.myDatas表,每条数据自动携带 InfluxDB 的时间戳(用于后续按时间排序补传)。

四、断点恢复阶段:网络恢复后自动补传

当 TCP 连接恢复时,系统基于历史时间戳定位断点,从 InfluxDB 读取待补传数据,批量完成补传并更新进度。

1.网络恢复检测与补传触发

(1)恢复检测: “status” 节点检测到 “tcp out” 节点恢复 “status.connected” 状态,触发 “switch” 节点的 “cont” 分支,“连接成功” 函数节点将global.conncetFlag设为true,并发送msg.delay=3000信号至 “trigger” 节点,设置 3 秒为补传周期(与 “周期性重发 3s” 逻辑匹配)。

(2)补传触发: “trigger” 节点每 3 秒发送一次触发信号,启动补传流程,避免短时间内高频请求导致数据库压力。

2.断点定位与待补传数据读取

(1)断点定位: “构造读数据” 函数节点(ID: 3a323d3113f99791)读取全局变量global.time(上次成功传输的时间戳),将其转为 ISO 格式(toISOString()),生成 InfluxDB 查询语句:SELECT * FROM "myDatas" WHERE time > '${UTCTIME}' LIMIT 1,即读取 “上次断点时间之后” 的 1 条待补传数据(LIMIT 1 确保批量处理不阻塞)。

(2)数据读取: “influxdb in” 节点(ID: abc727932e1bb82d)执行查询语句,从mydb.myDatas表中读取待补传数据,传入 “解析封装” 函数节点。

3.补传数据封装与发送

(1)数据解析:“解析封装” 节点从查询结果中提取湿度数据(data[0].hum),删除 InfluxDB 自动添加的time字段,重新封装为包含 “补传标记” 的 JSON 对象:{"hum":65,"uptime":${数据入库时间戳},"status":2}(status=2代表 “补传数据”),确保服务器能区分实时与补传数据。

(2)进度更新: 将当前补传数据的入库时间戳 + 200ms(避免重复读取同一条数据)更新至global.time,并通过 “写时间” 节点写入dataTime文件,完成进度同步。

(4)数据发送: 封装后的补传数据通过 “tcp out” 节点发送至目标服务器,完成单次补传;若数据库中无待补传数据(data.length < 1),则触发catch节点通过 “停止触发读” 函数节点发送msg.reset=true,暂停补传触发,避免无效查询。

五、核心保障机制:数据一致性与稳定性

1.数据去重与防重复发送

(1)时间戳偏移: 补传时将global.time更新为 “当前数据时间戳 + 200ms”,确保下次查询时跳过已补传数据,避免重复读取。

(2)状态标记区分: 实时数据(status=1)与补传数据(status=2)的标记,便于服务器端二次校验,防止重复存储。

2.异常捕获与容错

(1)数据库空查询处理: 当myDatas表无待补传数据时,“解析封装” 节点抛出 “database is empty” 错误,catch节点捕获后触发 “停止触发读”,暂停补传流程,减少资源消耗。

(2)传感器异常处理: “判断网络状态处理” 节点检测到传感器数据为null时,输出 “传感器异常” 警告,不执行后续缓存或发送逻辑,避免无效数据流转。

六、总结

该断点续传方案的核心是 “时间戳进度标记 + InfluxDB 本地缓存 + TCP 状态联动”,通过 Node-RED 的可视化节点编排,实现了 “初始化 - 实时传输 - 异常缓存 - 断点恢复” 的全自动化流程,无需手动干预。适用于传感器高频小数据、本地局域网传输、对数据可靠性要求高的场景(如工业设备监控、环境数据采集)。