websocket建立长连接与双向通信的核心是事件驱动与主动管理:new websocket()仅发起握手,需onopen触发才真正连通;“长连接”依赖心跳保活和手动重连;收发全靠onopen/onmessage/onclose/onerror四事件,send()须校验readystate === open;需自行实现重连、心跳、资源清理以避免断连失效和内存泄漏。

WebSocket 在 JavaScript 中建立长连接与双向通信,核心不是“一创建就通”,而是靠事件驱动 + 主动管理。new WebSocket() 只是发起握手请求,真正连通要等 onopen 触发;所谓“长连接”,需靠心跳保活和手动重连来维持。
用 new WebSocket() 初始化并确认连接成功
构造函数接收 ws:// 或 wss:// 开头的地址,协议必须匹配当前页面(https 页面只能用 wss,http 页面可用 ws):
- 执行 const ws = new WebSocket('wss://api.example.com/ws') 后,连接处于 CONNECTING 状态(readyState === 0),此时不能 send()
- 只有 ws.onopen = () => { ... } 被调用,才表示握手完成、双向通道真正建立(readyState 变为 1)
- 若 URL 错误、服务未启动或跨域被拒,会直接触发 onerror,不会进入 onopen
靠事件监听实现双向收发
WebSocket 是纯事件模型,没有回调或 Promise 接口,所有交互都依赖以下四个关键事件:
- onopen:连接就绪,可立即调用 send() 发送认证信息或初始化数据
- onmessage:接收到服务端消息,event.data 可能是字符串或 ArrayBuffer,需自行解析(如 JSON.parse)
- send():仅在 readyState === WebSocket.OPEN 时有效,否则静默失败
- onclose:连接断开时触发(含服务端关闭、网络中断、主动 close),但不会自动重连
手动维持“长连接”:重连 + 心跳
浏览器不提供自动重连或心跳,必须自己补全逻辑,否则 NAT 超时、短暂断网都会导致连接永久失效:
- 检测断开后延迟重试(如 3 秒),避免密集请求;建议限制重试次数,并采用指数退避
- 每 25–30 秒用 ws.send('ping') 发心跳,服务端需响应 'pong';客户端记录发送时间,超时未收则主动 close 并重连
- 每次 send 前检查 ws.readyState === WebSocket.OPEN,避免向已关闭连接写入
连接生命周期管理要点
不清理会引发内存泄漏或重复监听,尤其在单页应用中:
- 页面卸载前调用 ws.close(1000, 'leaving page'),释放资源
- onclose 回调里清除所有定时器(如心跳 setInterval)、取消 pending 操作
- 避免多次绑定同一事件(如反复 new WebSocket() 但没移除旧 onmessage),建议封装类统一管理监听器
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











