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

启用Socket.IO连接状态恢复后Payload格式变为数组的问题

Socket.IO连接状态恢复启用后Payload变为数组的问题

问题现象

启用连接状态恢复功能后,原本通过socket.emit(event, payload)发送的单个对象Payload,客户端接收时变成包含原对象和一个MongoDB文档ID的数组。

原发送的Payload:

{
    username: '_id',
    online: true,
    lastSeen: '2024-07-17T07:36:19.295Z'
}

客户端实际接收内容:

[
  {
        username: '_id',
        online: true,
        lastSeen: '2024-07-17T07:36:19.295Z'
  },
  66979cdf69bcbed06f8f6518
]

服务端配置

const io = new Server(server, {
      pingTimeout: 60000,
      cors: {
        origin: '*'
      },
      connectionStateRecovery: {
        // 会话和数据包的备份时长
        maxDisconnectionDuration: 2 * 60 * 1000,
        // 恢复成功后是否跳过中间件
        skipMiddlewares: true
      }
    });

原因分析

这不是Socket.IO的默认行为,问题出在MongoDB适配器与连接状态恢复功能的兼容性上:启用连接状态恢复后,MongoDB适配器会将待重发的数据包存储到数据库中,恢复过程中重新推送数据时,错误地将数据库文档的_id附加到Payload末尾,导致客户端接收到数组格式的数据。

解决方法

  • 客户端临时适配:在接收事件时判断数据格式,若为数组则取第一个元素作为实际Payload:
    socket.on('目标事件名', (data) => {
      const actualPayload = Array.isArray(data) ? data[0] : data;
      // 后续业务逻辑处理
    });
    
  • 升级适配器版本:该问题属于MongoDB适配器的已知兼容性bug,升级到最新版的socket.io-adapter-mongo即可修复。
  • 调整服务端配置:若无需严格的消息重发保障,可暂时禁用连接状态恢复;或自定义恢复逻辑,避免适配器自动附加文档ID。

参考文档内容翻译(原免责声明)

连接状态恢复目前处于实验阶段,后续版本可能会调整API。此外,并非所有第三方适配器都完全支持该功能,使用时可能出现兼容性问题,建议在生产环境中谨慎使用并充分测试。

内容的提问来源于stack exchange,提问作者Adithya Gopakumar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 18:38:18