如何用WebSocket实现定时发消息?Node.js代码运行报错求修复
报错直接原因
ws库的send()方法不支持直接传入JavaScript对象作为参数,仅接收字符串、Buffer、ArrayBuffer等类型的参数,你代码中直接传入对象触发了类型错误。同时代码还存在其他几个会导致运行异常的问题,需要一并修复:
- 每次收到前端消息都会创建新的2秒定时器,会出现重复发送、内存泄漏问题
- 客户端断开连接后未清理定时器,会继续执行无效的查询和发送逻辑
- 异步查询逻辑的错误直接抛出未捕获,会触发Node.js的未处理Promise拒绝警告
修复后的服务端代码
const WebSocket = require("ws"); const db = require('./db') const wss = new WebSocket.Server({port: 5000}); wss.on("connection", ws => { console.log("New Client Connected!"); // 把定时器挂载到ws实例上,方便后续清理 ws.sendInterval = null ws.on("message", data => { // 打印收到的字符串内容,也可以转成字符串判断是不是确认消息 console.log(data.toString()); // 先清理之前的定时器,避免重复创建 if(ws.sendInterval) clearInterval(ws.sendInterval) // 启动新的定时器 ws.sendInterval = setInterval(()=> getSelPos(ws), 2000); }); ws.on("close", () => { console.log("Client has Disconnected"); // 客户端断开后清理定时器 if(ws.sendInterval) clearInterval(ws.sendInterval) }); // 连接出错也清理定时器 ws.on('error', () => { if(ws.sendInterval) clearInterval(ws.sendInterval) }) }); const getSelPos = async(ws) =>{ try { const result = await db.pool.query("select value from db.tags where tag in ('1006', '1004', '1002')"); // 把对象序列化为JSON字符串再发送 ws.send(JSON.stringify({ selector: result[2].value.toString(), pressure: result[1].value.toString(), temperature: result[0].value.toString() })); console.log(result); } catch (err) { // 不要直接抛错,打印日志即可,避免服务端崩溃 console.error('查询或发送失败:', err) } }
前端代码调整
服务端发送的是JSON字符串,前端收到后需要反序列化为对象才能使用:
const ws = new WebSocket("ws://localhost:5000"); ws.addEventListener("open", () => { console.log("We are connected!"); ws.send("Hello!"); }); ws.addEventListener("message", ({data}) => { // 反序列化JSON字符串为对象 const resData = JSON.parse(data) console.log(resData); // 后续可以用resData里的字段更新组件状态 });
内容的提问来源于stack exchange,提问作者Cm1602
相关产品推荐
相关产品推荐

