You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:00:48