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

Node.js中OSC消息服务器的WebSocket自动重连实现

解决WebSocket自动重连问题及脚本优化建议

自动重连逻辑实现

你遇到的ECONNREFUSED错误是WebSocket初始连接失败或后续断开导致的,通过封装连接逻辑、监听断开/错误事件即可实现自动重连:

  1. 将创建WebSocket的逻辑抽为独立函数,方便重复调用
  2. 监听close事件触发重连,设置固定间隔避免频繁重试
  3. 完善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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 22:41:08