WebSocket 是独立于 HTTP 的 TCP 上层协议,需服务端支持、正确握手及生命周期管理;构造函数仅需 ws:// 或 wss:// 开头的 URL,readyState 异步变化,须监听 open 事件后发送消息,代理需配置 Upgrade 和 Connection 头。
WebSocket 是
浏览器
与服务器之间建立全双工、持久化通信通道的协议,不是 HTTP 的替代品,而是一种独立的 TCP 上层协议;JavaScript 中用
构造函数就能发起连接,但成败关键不在“怎么写”,而在服务端是否真正支持、握手是否通过、以及连接生命周期是否被正确管理。
WebSocket 构造函数怎么用?参数和状态要注意什么?
只传一个
字符串即可初始化,但必须是
或
开头(不能用
)。连接建立是异步的,
会经历
(CONNECTING)、
(OPEN)、
(CLOSING)、
(CLOSED)四个值,绝不能在
后立刻发消息。
必须和服务端实际暴露的 WebSocket 端点完全一致,包括路径(如
),多一个斜杠或少一个都可能 404
构造后立即检查
一定是
,应监听
事件再发送数据
某些代理(如 Nginx)默认不转发 WebSocket 升级头,会导致连接卡在 CONNECTING 状态,需显式配置
和
头
为什么 onmessage 收不到数据?常见断连原因有哪些?
收不到消息不等于没发出去,更可能是服务端没响应、心跳没维持、或连接已被静默关闭。浏览器不会主动重连,
触发后连接对象就不可用,再次调用
会抛出
。
服务端未实现
心跳,中间网络设备(如 NAT、
防火墙
)可能在 60 秒无流量后主动断开 TCP 连接
发送了非字符串或非
类型的数据(如直接传 Object),
会静默失败,控制台无提示
多个标签页共用同一 WebSocket 实例(比如挂载在
),一个页面刷新或关闭会导致其他页面的
对象进入 CLOSED 状态
Chrome 开发者工具的 Network 面板里看不到 WebSocket 的帧内容,需在 Console 中用
手动监听才能调试
如何安全地重连?避免无限循环或资源泄漏?
自动重连必须带退避策略和最大重试次数,否则网络恢复瞬间可能触发大量并发连接请求,压垮服务端或触发限流。每次新建
实例前,务必清除旧实例的事件监听器,并检查其
是否已为
。
Comet AI 浏览器
下载 Comet AI 浏览器,体验由 Perplexity AI 驱动的革命性上网方式。内置 AI 助手可实时总结网页、跨标签页对比信息、自动执行任务。告别繁琐操作,让 AI 成为你的浏览副驾,大幅提升研究与工作效率。支持 Windows、macOS、Android 和 iOS。
下载
立即学习
“
Java免费学习笔记(深入)
”;
用
实现指数退避(如 1s → 2s → 4s → 8s),超过 5 次失败后暂停重连并提示用户
在
回调里设置标志位(如
),区分是用户主动关闭还是异常断开
避免在
里直接重连——它可能在
前就触发(例如 DNS 解析失败),此时重连毫无意义
使用
无法中断 WebSocket 连接,它只对
有效;真正的清理只能靠
+ 置空引用
真实项目里最难的从来不是“怎么连上”,而是“怎么知道它什么时候断了、为什么断、该不该重连、重连时要不要清缓存、用户离线期间的消息怎么补”。这些逻辑没法靠一个
解决,得结合业务状态、心跳响应、服务端 ACK 机制一起设计。
WebSocketurlws://wss://http://readyState0123new WebSocket(...)urlws://localhost:3000/wsws.readyState === WebSocket.OPENfalseopenUpgradeConnectionconst ws = new WebSocket('wss://api.example.com/realtime');
ws.onopen = () => {
console.log('Connected');
ws.send(JSON.stringify({ type: 'auth', token: 'abc123' }));
};
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log('Received:', data);
};
ws.onerror = (error) => {
console.error('WebSocket error:', error);
};
ws.onclose = (event) => {
console.log('Disconnected', event.code, event.reason);
};onclosesend()InvalidStateErrorPING/PONGArrayBuffersend()window.wswsws.addEventListener('message', ...)WebSocketreadyStateCLOSEDsetTimeoutoncloseisManuallyClosed = falseonerroronopenAbortControllerfetchws.close()new WebSocket()