Node.js中OSC消息服务器的WebSocket自动重连实现
解决WebSocket自动重连问题及脚本优化建议
自动重连逻辑实现
你遇到的ECONNREFUSED错误是WebSocket初始连接失败或后续断开导致的,通过封装连接逻辑、监听断开/错误事件即可实现自动重连:
- 将创建WebSocket的逻辑抽为独立函数,方便重复调用
- 监听
close事件触发重连,设置固定间隔避免频繁重试 - 完善
open和error事件的日志输出,便于排查状态
优化后的完整代码
const osc = require('osc'); const WebSocket = require('ws'); // 提取常量,统一维护配置项 const WS_SERVER_URL = 'ws://192.xxx.x.xxx:8000'; const OSC_CLIENTS = { clientA: { ip: '10.4.0.95', port: 9004 }, clientB: { ip: '10.4.0.94', port: 9003 } }; const TRIGGER_MAPPING = { '/bank/1/trig/3': '3', '/bank/1/trig/2': '5', '/bank/1/trig/1': '7' }; let ws; const RECONNECT_INTERVAL = 5000; // 重连间隔5秒 // 创建WebSocket连接的复用函数 function createWebSocket() { ws = new WebSocket(WS_SERVER_URL); ws.on('open', () => { console.log('WebSocket连接成功'); }); ws.on('close', () => { console.log('WebSocket连接断开,5秒后尝试重连...'); setTimeout(createWebSocket, RECONNECT_INTERVAL); }); ws.on('error', (err) => { console.error('WebSocket错误:', err.message); }); } // 初始化WebSocket createWebSocket(); // 初始化UDP端口 const udp = new osc.UDPPort({ localAddress: '0.0.0.0', localPort: 8000, }); udp.on('ready', () => { console.log('OSC Server正在监听'); }); udp.on('error', (err) => { console.error('UDP端口错误:', err.message); }); // 处理OSC消息 udp.on('message', (msg, timeTag, info) => { console.log('收到OSC消息:', msg); // 转发消息到clientA(排除自身来源) if (info.address !== OSC_CLIENTS.clientA.ip) { udp.send(msg, OSC_CLIENTS.clientA.ip, OSC_CLIENTS.clientA.port); } // 转发播放头消息到clientB(排除自身来源) if (msg.address.startsWith('/mov/moviePlayhead') && info.address !== OSC_CLIENTS.clientB.ip) { udp.send(msg, OSC_CLIENTS.clientB.ip, OSC_CLIENTS.clientB.port); } // 统一处理触发消息,发送到WebSocket const triggerType = TRIGGER_MAPPING[msg.address]; if (triggerType) { if (ws.readyState === WebSocket.OPEN) { ws.send(JSON.stringify({ event: 'kaleidoscope', action: 'play', type: triggerType })); } else { console.warn('WebSocket未连接,无法发送触发消息'); } } // 可选:启用停止逻辑 /* else { if (ws.readyState === WebSocket.OPEN) { ws.send(JSON.stringify({event:'kaleidoscope', action: 'stop'})); } } */ }); udp.open();
脚本优化建议
- 常量集中管理:把固定的IP、端口、OSC地址映射抽为常量,后续修改无需在代码中多处查找
- 合并重复逻辑:用映射表替代多个
else if判断,简化触发消息的处理逻辑 - 完善错误捕获:给UDP端口添加
error监听,避免未捕获的错误导致进程崩溃 - 代码风格统一:用
const/let替代var,使用箭头函数让代码更简洁易读 - 日志增强:添加连接状态、错误信息的日志,方便快速定位问题
- 重连策略升级:可改为指数退避(如第一次5秒、第二次10秒,上限30秒),避免对服务器造成过多重试请求
内容的提问来源于stack exchange,提问作者ksatione
相关产品推荐
相关产品推荐

