WebSocket流控需前后端协同实现,核心是“按需发送、确认驱动、节奏可控”:前端通过bufferedAmount和分片控制节制发送,服务端通过ACK确认形成闭环,并结合连接层限速与异常降级保障稳定性。

WebSocket本身不内置流控机制,大规模二进制文件传输时容易因发送过快导致接收端缓冲区溢出、主线程阻塞或内存飙升。真正可行的流控必须由前后端协同实现,核心是“按需发送、确认驱动、节奏可控”。
前端主动节制发送节奏
不能一拿到ArrayBuffer就连续调用ws.send()。关键在于利用bufferedAmount和手动分片控制:
- 每次发送前检查
ws.bufferedAmount,若超过阈值(如2MB),暂停发送并等待onbufferedamountlow事件(需浏览器支持)或轮询延时重试 - 将大文件切分为固定大小分片(推荐64KB–256KB),每片发送后记录序号,不等确认不发下一片
- 使用
setTimeout或requestIdleCallback把分片发送任务分散到空闲帧,避免卡顿
服务端反馈确认机制
单靠前端节制不够,必须引入轻量级ACK回传,形成闭环:
- 前端每发送一个分片,附带唯一序号(如
{id: "upload_abc", seq: 12, data: ...}) - 服务端成功写入该分片后,立即通过同一WebSocket连接推送
{"ack": 12} - 前端收到ACK才触发下一分片发送;超时未收则重发,最多3次
连接层与协议层协同限速
避免在应用层做复杂调度,优先用底层能力降低开销:
立即学习“前端免费学习笔记(深入)”;
- 设置
ws.binaryType = 'arraybuffer',确保发送的是原始字节,跳过字符串序列化开销 - 服务端限制单连接并发接收分片数(如最多缓存5个未ACK分片),超出则返回
{"reject": "backpressure"},前端退避重试 - 对持续高速上传场景,可协商动态调整分片大小:初始小片试探,稳定后放大(如从64KB升至512KB)
异常与降级处理
真实网络中丢包、断连、GC暂停都可能发生,流控策略需有韧性:
- WebSocket断开时,前端保存已发最大seq和本地offset,重连后发送
{"resume": "upload_abc", "from_seq": 42}请求续传 - 若连续多次ACK延迟>3秒,自动降级为更小分片+更长间隔,防止雪崩
- 监听
ws.onclose和onerror,清除未完成的发送定时器,避免内存泄漏



















