浏览器无法捕获或响应 websocket 协议层 ping/pong 帧(0x09/0x0a),其由底层自动处理;所谓“服务端发送 ping”实为应用层文本消息(如 "ping" 或 {"type":"ping"}),需在 onmessage 中识别并主动 send("pong") 或对应 json 回复。

浏览器 WebSocket API 不提供直接处理协议层 Ping/Pong 帧(opcode 0x09 / 0x0A)的能力,服务端发来的 Ping 帧会被底层自动响应 Pong,**你无需、也无法在 JS 中捕获或手动回复它**。但如果你看到服务端“发送了 ping”,实际大概率是它在应用层发了一条文本消息,比如 "ping" 或 {"type":"ping"} —— 这才是你需要监听并主动回复的。
判断并响应应用层 ping 消息
服务端若用普通文本模拟 ping,客户端需在 onmessage 中识别内容,并立即调用 send("pong"):
- 检查
event.data是否为字符串"ping",或解析 JSON 后判断type === "ping" - 确认
ws.readyState === WebSocket.OPEN再发送,避免报错 - 直接
ws.send("pong")即可,无需额外格式;服务端应约定只认这个固定字符串
不要混淆协议层和应用层
WebSocket 协议规定:收到 opcode 0x09 的 Ping 帧时,浏览器必须自动回一个 payload 完全相同的 Pong 帧(0x0A),这个过程完全透明,JS 无访问权限。所以:
- 你在 Network 面板或抓包工具里看到的 “Ping” 帧,不会触发
onmessage - 如果你在
onmessage里收到了内容,那一定是服务端用send("ping")发的普通消息,不是协议帧 - 强行尝试用
ArrayBuffer构造 0x09 帧并通过send()发送,会抛出SyntaxError
推荐的服务端-客户端协作方式
为保持语义清晰、便于调试和兼容,建议统一走应用层心跳:
- 服务端定时发
{"type":"ping","ts":1727228760},客户端只认type === "ping" - 客户端收到后立刻回
{"type":"pong","ts":1727228760,"rtt":23}(可选带上时间戳和 RTT) - 双方都忽略原生 Ping/Pong 帧,专注验证业务消息的往返时效性
不复杂但容易忽略:真正的连接健康,靠的是你能看见、能校验、能超时控制的消息流,而不是看不见摸不着的底层帧。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











