websocket比http轮询快在省去每次通信的tcp握手、tls协商和http头解析等固定开销,实现低延迟、低开销的双向实时通信,但仅适用于高频小消息场景。

能,但前提是用对场景、避开浏览器和网络层的固有限制。 WebSocket 不是万能加速器,它解决的是 HTTP 轮询带来的连接开销和延迟毛刺,而不是把 200ms 的网络 RTT 变成 2ms。
WebSocket 比 AJAX 轮询快在哪?
关键不是“协议更快”,而是省掉了每次通信的 TCP 握手、TLS 协商、HTTP 头解析、连接复用判断等固定开销。轮询哪怕设成 1s 一次,每秒也至少新建/关闭 1 次连接(或维持长连接但反复发请求头);而 WebSocket 建连一次后,后续所有 send() 都走裸数据帧,头部只有 2–14 字节。
- 适合高频小消息:如聊天打字提示、协作光标位置、实时股价 tick
- 不适合大文件传输:没有内置分片、断点续传、优先级控制,
send()传 5MB 二进制会阻塞后续消息 - 首次建连耗时 ≈ 2×RTT + TLS 时间,比单次 HTTP GET 还慢——别用它替代首页资源加载
为什么 onmessage 没触发?常见连接态陷阱
90% 的“连上了但收不到消息”问题出在状态误判:readyState 是 OPEN 才能发收,但很多人在 onopen 回调里立刻 send(),却忽略服务端可能还没完成鉴权或房间加入逻辑。
- 永远检查
ws.readyState === WebSocket.OPEN再发消息,不要只信onopen -
onmessage收到的是MessageEvent,event.data可能是string或Blob,取决于服务端发的是文本帧还是二进制帧 - Chrome DevTools 的 Network 标签页不显示 WebSocket 数据帧,得用
ws.onmessage = e => console.log(e.data)实时看
如何处理断线与自动重连?别依赖 onclose
onclose 只在连接明确关闭时触发(比如服务端调 close()),但网络闪断、NAT 超时、代理静默丢包时,前端可能长时间卡在 OPEN 状态,实际已收不到消息。
- 必须实现应用层心跳:定时发
ping消息(如ws.send(JSON.stringify({type:'ping'}))),服务端回pong,超时未响应则主动close()并重连 - 重连间隔要递增(如 1s → 2s → 4s),避免雪崩;最大重试次数建议 ≤5 次,之后提示用户检查网络
- 重连前清空待发送队列,否则新连接一建立就疯狂
send()积压消息,可能触发服务端限流
真正难的不是写通 new WebSocket(),而是让连接在弱网、切后台、系统休眠、iOS Safari 后台标签页冻结这些真实场景下还能维持语义正确的消息可达性——这需要客户端心跳、服务端连接保活、消息去重、离线缓存策略一起配合,单靠 WebSocket API 本身做不到。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











