问题描述
packages/web/src/ws/client.ts 的 handleClose() 在 WebSocket 重连时,不清空以下 Map:
orphanBinaryPayloads(line 93)
pendingReplayStreamIds(line 88)
服务端每次新建 WsClient 实例时,nextStreamId 从 1 重新计数。重连后新连接的 streamId=1 帧会命中旧连接遗留在 Map 中的 entry,导致 replay 数据路由到错误的处理器,出现终端输出乱码或 replay promise 永远不 resolve。
复现场景
- 用户打开终端,触发 replay 请求(streamId=1)
- 网络闪断,replay binary 帧尚未到达,对应 streamId 在
pendingReplayStreamIds 中留存
- WebSocket 自动重连,服务端重新从 streamId=1 开始
- 新连接的第一个 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,避免旧状态污染新连接。
问题描述
packages/web/src/ws/client.ts的handleClose()在 WebSocket 重连时,不清空以下 Map:orphanBinaryPayloads(line 93)pendingReplayStreamIds(line 88)服务端每次新建 WsClient 实例时,
nextStreamId从 1 重新计数。重连后新连接的streamId=1帧会命中旧连接遗留在 Map 中的 entry,导致 replay 数据路由到错误的处理器,出现终端输出乱码或 replay promise 永远不 resolve。复现场景
pendingReplayStreamIds中留存相关代码
coder-studio/packages/web/src/ws/client.ts
Lines 450 to 465 in 490e555
修复建议
在
handleClose()中清空这两个 Map,并 reject 所有 pending 的 replay promise,避免旧状态污染新连接。