如何在JavaScript中实现同数据多WebSocket冗余连接以保障服务可用性?
多WebSocket冗余传输的正确实现方案
原代码的核心问题
- 触发
onopen时盲目给所有WebSocket发配置,甚至引用了未定义的ws5,直接报错 - 所有WebSocket的消息都无脑推入队列,导致重复数据疯狂堆积
- 完全没处理连接失败、断开后的重连逻辑
- 没有区分正常/异常连接,无法保证仅用可用连接提供数据
正确实现思路
- 并行初始化所有WebSocket,避开串行连接的高延迟问题
- 每个WebSocket独立处理自身的连接、消息、错误、断开逻辑
- 维护活跃连接列表,仅从正常连接收数据,同时做去重(因为多源数据格式完全一致)
- 失败的连接自动重试,确保冗余性不丢失
完整代码实现
let queue = []; // 存储所有WebSocket的连接信息与状态 const wsConnections = [ { url: 'wss://firstsource.com/ws/', instance: null, isActive: false }, { url: 'wss://secondsource.com/ws/', instance: null, isActive: false }, { url: 'wss://thirdsource.com/ws/', instance: null, isActive: false }, { url: 'wss://fourthsource.com/ws/', instance: null, isActive: false } ]; // 用于去重的标识(根据实际数据结构调整,比如用数据的唯一ID) let lastReceivedKey = null; // 批量初始化所有WebSocket连接 function initAllConnections() { wsConnections.forEach(conn => createSingleConnection(conn)); } // 创建单个WebSocket连接并绑定生命周期事件 function createSingleConnection(conn) { conn.instance = new WebSocket(conn.url); // 连接成功:标记活跃+发送配置 conn.instance.onopen = () => { conn.isActive = true; conn.instance.send('{"config":"2.0"}'); console.log(`连接成功:${conn.url}`); }; // 接收消息:去重后再入队 conn.instance.onmessage = (msg) => { // 解析数据,生成唯一标识(示例用完整JSON字符串,实际可改用数据自带的唯一ID) const data = JSON.parse(msg.data); const currentKey = data.id || JSON.stringify(data); if (currentKey !== lastReceivedKey) { lastReceivedKey = currentKey; queue.push(data); console.log('新数据已入队'); } }; // 连接出错:标记非活跃+触发重连 conn.instance.onerror = () => { conn.isActive = false; console.error(`连接出错:${conn.url}`); retryConnection(conn); }; // 连接关闭:标记非活跃+触发重连 conn.instance.onclose = () => { conn.isActive = false; console.log(`连接关闭:${conn.url}`); retryConnection(conn); }; } // 延迟重试连接(避免频繁请求) function retryConnection(conn) { setTimeout(() => { console.log(`尝试重连:${conn.url}`); createSingleConnection(conn); }, 3000); // 3秒后重试,可根据业务调整间隔 } // 启动所有连接 initAllConnections();
关键细节说明
- 并行连接:所有WebSocket同时初始化,彻底解决串行连接的高延迟问题
- 独立管理:每个连接的生命周期完全独立,一个连接出错不会影响其他连接
- 数据去重:通过唯一标识过滤重复数据,避免队列被重复内容塞满
- 自动重连:连接失败/断开后自动重试,始终维持冗余能力
- 状态追踪:用
isActive标记连接状态,后续可扩展优先使用特定连接等逻辑
内容的提问来源于stack exchange,提问作者Norbert
相关产品推荐
相关产品推荐

