WebSocket Client

WebSocket Client 是前端通过 WebSocket 协议与服务器进行双向实时通信的模块。在 AI 应用中,WebSocket 适用于需要双向通信的场景(如语音对话、实时协作)。

#type / concept #status / evergreen #tech / frontend #tech / network

[!info] related notes

WebSocket Client

一句话定义

WebSocket Client 是前端通过 WebSocket 协议与服务器进行双向实时通信的模块。与 SSE 的单向推送不同,WebSocket 支持双向通信,适合需要客户端频繁发送数据的场景。

它解决什么问题

SSE 是单向的(服务器 → 客户端)。某些 AI 场景需要双向通信:

  • 语音对话: 客户端持续发送音频流,服务器持续返回识别结果
  • 实时协作: 多人同时编辑,需要双向同步
  • 交互式 Agent: 用户可以随时中断、修改指令

SSE vs WebSocket 选型

SSEWebSocket
方向单向(服务器→客户端)双向
协议HTTP独立的 WS 协议
自动重连✅ 原生支持❌ 需手动实现
二进制❌ 只支持文本✅ 支持
适用LLM 流式输出语音、实时协作

大多数 AI 对话场景用 SSE 就够了。 WebSocket 只在需要双向通信时才用。

核心原理

WebSocket 基础

class WSClient {
  private ws: WebSocket | null = null;
  private reconnectAttempts = 0;

  connect(url: string) {
    this.ws = new WebSocket(url);

    this.ws.onopen = () => {
      console.log('Connected');
      this.reconnectAttempts = 0;
    };

    this.ws.onmessage = (event) => {
      const data = JSON.parse(event.data);
      this.handleMessage(data);
    };

    this.ws.onclose = () => {
      this.reconnect();
    };

    this.ws.onerror = (error) => {
      console.error('WebSocket error:', error);
    };
  }

  send(data: any) {
    if (this.ws?.readyState === WebSocket.OPEN) {
      this.ws.send(JSON.stringify(data));
    }
  }

  private reconnect() {
    if (this.reconnectAttempts < 5) {
      setTimeout(() => {
        this.reconnectAttempts++;
        this.connect(this.ws!.url);
      }, Math.pow(2, this.reconnectAttempts) * 1000);
    }
  }

  disconnect() {
    this.ws?.close();
  }
}

心跳保活

class WSClient {
  private heartbeatInterval: NodeJS.Timeout | null = null;

  private startHeartbeat() {
    this.heartbeatInterval = setInterval(() => {
      this.send({ type: 'ping' });
    }, 30000);
  }

  private stopHeartbeat() {
    if (this.heartbeatInterval) {
      clearInterval(this.heartbeatInterval);
    }
  }
}

常见坑

  1. 不做重连: 网络抖动后连接断开,无法恢复
  2. 不做心跳: 连接被中间代理断开(Nginx 默认 60s 超时)
  3. 不处理二进制: 语音场景需要处理 ArrayBuffer
  4. SSE 够用却用 WebSocket: 增加不必要的复杂度
  5. 不做消息队列: 连接断开期间的消息丢失

参考资料

创建于 2026/6/30 更新于 2026/7/15