使用SerialPort与Socket.io时重复发送消息的问题求助
问题分析与解决方案
嘿,这个坑我太熟了!你遇到的是事件监听重复绑定的典型问题——每次Web页面刷新触发socket的connection事件时,你都给parser又加了一个data事件监听。第一次连接加1个,刷新后再加1个,现在就有2个监听等着串口数据,数据一来自然就触发2次,次数随刷新次数叠加。
问题核心代码
你原来的代码里,每次新socket连接进来都会执行这段:
parser.on('data', (data) => { console.log("Hello world"); io.sockets.emit("serverMessage", { message: data }); });
这就导致data事件的监听器越来越多,每多一个连接就多一个监听器,串口数据触发时所有监听器都会执行一遍。
修复方案
把串口数据的监听逻辑移到io.on('connection')外面,让它只初始化一次,不管有多少客户端连接,串口数据到来时只处理一次然后广播给所有客户端:
修改后的服务端代码:
const SerialPort = require('serialport'); const ReadLine = require('@serialport/parser-readline'); const Express = require('express'); const Socket = require('socket.io'); // Web server const app = Express(); const server = app.listen(3000, function () { console.log("Server listening on port 3000"); }); // Socket web const io = Socket(server); const serialPort = new SerialPort("COM3", { baudRate: 9600 }); const parser = new ReadLine(); serialPort.pipe(parser); // 把串口监听移到connection事件外面,只绑定一次 parser.on('data', (data) => { console.log("Hello world"); io.sockets.emit("serverMessage", { message: data }); }); io.on('connection', function(socketConnection) { console.log("New connection"); // 这里只处理和单个socket连接相关的逻辑,比如客户端消息接收、断开事件等 });
修复逻辑说明
- 串口数据的监听只在服务启动时绑定一次,后续不管多少客户端连接/刷新,都不会再新增监听器
- 当串口有数据到来时,直接通过
io.sockets.emit()广播给所有在线的socket客户端,确保每条数据只发送一次 - 如果需要针对单个客户端发送特定数据(比如客户端请求后再发),可以在
connection事件里处理,但串口的全局监听还是要放在外面
客户端代码不需要修改,保持原来的逻辑就行。
内容的提问来源于stack exchange,提问作者Candy
相关产品推荐
相关产品推荐

