websocket限流需客户端主动实现,核心是监控bufferedamount水位、令牌桶控速、节流防抖混合策略及服务端协同反馈。

WebSocket 本身不控制发送频率,所有限流逻辑必须由客户端主动实现。关键不是“不让发”,而是让 send() 调用节奏匹配网络与服务端的实际承载能力——避免 bufferedAmount 持续上涨、连接被强制关闭,或服务端触发熔断。
用 bufferedAmount 做实时水位监控
这是浏览器唯一提供的原生背压信号,反映当前已调用 send() 但尚未发出的字节数。
- 不要在 send() 后立刻读取,此时值常为 0;建议每 100ms 主动检查一次
- 设定合理阈值(如 64KB),连续 2–3 次超过即进入节流模式
- 触发限速后暂停发送,等 bufferedAmount 回落至阈值 30% 以下再恢复
- 注意:Chrome 对二进制帧统计不准,文本帧更可靠;Firefox 统计更准
封装带令牌桶的发送器
比简单 setTimeout 更贴近真实流控语义,适合稳定速率场景(如每秒最多 8 条状态更新)。
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- 初始化时设定最大令牌数(如 8)和补充间隔(如 1000ms 补 1 个)
- 每次 send() 前尝试扣减令牌;无令牌则入队等待,或按策略丢弃低优先级消息
- 用 setInterval 平滑补发,避免定时器漂移;也可用 requestIdleCallback 减少主线程压力
- 高优消息(如错误告警、心跳)可绕过令牌桶,直接发送
结合节流与防抖的混合策略
适用于数据源高频但业务语义分层的场景,比如传感器上报 + 用户操作提交共存。
- 节流用于“快照类”数据:每 200ms 只发最新一条(如实时坐标)
- 防抖用于“终态类”数据:静默 300ms 后才发最后一次(如表单配置变更)
- 推荐攒批兜底:50ms 时间窗口 + 最多 20 条合并发送,避免小包泛滥
- 每次 send 前必须校验 ws.readyState === WebSocket.OPEN,失败时清空定时器防泄漏
配合服务端协同降频
前端单方面限流只是半解,需服务端暴露反馈信号才能闭环。
- 服务端处理完消息后返回 ACK(含 seqId),客户端据此释放滑动窗口
- 监听服务端推送的背压信号(如 { type: 'BACKPRESSURE', level: 'HIGH' }),动态下调 maxRate
- 服务端应配置合理 maxBackpressure(如 1MB)并设 closeOnBackpressureLimit = false,把控制权交还前端
- 断连重连后,清空本地待发队列,避免堆积旧消息集中爆发
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










