JavaScript如何实现WebSocket通信?

WebSocket是全双工持久化协议,需用ws://或wss://创建实例,通过readyState(0-3)判断连接状态,监听onopen/onmessage/onerror/onclose事件,send()发送数据,注意断线重连、心跳保活及前后端协议约定。

WebSocket 是浏览器与服务器之间建立全双工、持久化连接的协议,相比 HTTP 轮询更高效、实时性更强。实现 WebSocket 通信核心是创建 WebSocket 实例,监听事件,并通过 send() 发送数据。

创建连接并监听状态

使用 new WebSocket(url) 初始化连接,URL 必须以 ws://(非加密)或 wss://(加密,推荐用于生产环境)开头。连接过程有四个关键状态,可通过 readyState 判断:

  • 0(CONNECTING):正在连接中,此时不能发送消息
  • 1(OPEN):连接已建立,可收发数据
  • 2(CLOSING):正在关闭连接
  • 3(CLOSED):连接已关闭或连接失败

建议在 onopen 回调中确认连接就绪后再发送数据;用 onerror 捕获连接异常(如跨域、URL 错误、网络中断)。

收发消息的核心操作

消息通信基于事件驱动:

  • onmessage:接收服务器推送的数据,event.data 是原始消息(可能是字符串或 Blob/ArrayBuffer,需根据服务端约定解析)
  • send(data):向服务端发送数据,支持字符串、ArrayBufferBlob;传入对象需先 JSON.stringify()
  • close(code, reason):主动关闭连接,可选传入关闭码(如 1000 表示正常关闭)和原因字符串

例如:ws.send(JSON.stringify({ type: 'login', user: 'Alice' })) 是常见登录请求格式。

处理断线重连与心跳保活

WebSocket 连接可能因网络抖动、服务重启等意外断开,前端应主动管理连接生命周期:

  • 监听 onclose 事件,在状态变为 CLOSED 后延迟几秒自动重连(避免密集重试)
  • 服务端通常要求客户端定期发送心跳包(如每 30 秒 ws.send('ping')),否则主动断开闲置连接
  • 建议封装一个 WebSocketClient 类,内置重连计数、指数退避、心跳定时器等逻辑

注意事项与常见问题

实际开发中容易忽略这些细节:

  • 确保服务端已部署 WebSocket 服务(如 Node.js 的 ws 库、Nginx 需配置 UpgradeConnection 头)
  • 浏览器控制台可查看 Network → WS 标签页,检查连接状态和收发帧内容
  • 不要在 onmessage 中执行耗时同步操作,避免阻塞后续消息;必要时用 setTimeoutrequestIdleCallback 延迟处理
  • 关闭页面前调用 ws.close(),避免资源泄漏(也可在 beforeunload 中处理)

基本上就这些。WebSocket 本身 API 很简洁,难点在于连接稳定性保障和前后端协议约定。