Skip to content

[BUG] WebSocket 重连后 orphanBinaryPayloads / pendingReplayStreamIds 未清空,导致跨连接数据污染 #18

@pallyoung

Description

@pallyoung

问题描述

packages/web/src/ws/client.tshandleClose() 在 WebSocket 重连时,不清空以下 Map:

  • orphanBinaryPayloads(line 93)
  • pendingReplayStreamIds(line 88)

服务端每次新建 WsClient 实例时,nextStreamId 从 1 重新计数。重连后新连接的 streamId=1 帧会命中旧连接遗留在 Map 中的 entry,导致 replay 数据路由到错误的处理器,出现终端输出乱码或 replay promise 永远不 resolve。

复现场景

  1. 用户打开终端,触发 replay 请求(streamId=1)
  2. 网络闪断,replay binary 帧尚未到达,对应 streamId 在 pendingReplayStreamIds 中留存
  3. WebSocket 自动重连,服务端重新从 streamId=1 开始
  4. 新连接的第一个 replay binary 帧(streamId=1)命中旧的 pending entry,数据污染

相关代码

} catch (err) {
console.error(`Error in event listener for ${topic}:`, err);
}
}
}
}
private isTerminalBinaryEventData(data: unknown): data is TerminalBinaryEventData {
return (
typeof data === 'object' &&
data !== null &&
'transport' in data &&
'streamId' in data &&
'size' in data &&
(data as { transport?: unknown }).transport === 'binary'
);

修复建议

handleClose() 中清空这两个 Map,并 reject 所有 pending 的 replay promise,避免旧状态污染新连接。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions