SSE和WebSocket

1. SSE 适用场景(单向、仅后端推文本)

核心特点:基于 HTTP、只能后端发给前端、只适合文本流式输出

  • AI 问答、文案生成、代码流式返回、实时日志、消息通知
  • 需求:只需要源源不断接收后端增量文字,不需要前端频繁实时上传数据
SSE 精简封装(AI 逐字流式,单向推送,代码最少)

适用:纯服务端下发、逐字打字、大模型流式输出

复制代码
// sseStream.js 极简封装
export function createSSEStream(url, handlers) {
  const source = new EventSource(url, { withCredentials: true });
  let timer = null;

  // 正常分片消息
  source.onmessage = (e) => {
    const res = JSON.parse(e.data);
    // 逐字片段追加
    if (res.data) handlers.onChunk?.(res.data);
    // 流式结束
    if (res.isEnd) {
      handlers.onEnd?.();
      source.close();
    }
  };

  // 错误重连控制
  source.onerror = () => {
    handlers.onError?.();
    // 连续失败关闭,避免无限重连
    timer = setTimeout(() => source.close(), 8000);
  };

  // 主动停止流式输出
  const stop = () => {
    clearTimeout(timer);
    source.close();
  };

  return { stop };
}
使用示例
复制代码
// 发起对话流式输出
const stream = createSSEStream('/api/sse/stream?sessionId=xxx&token=xxx', {
  // 逐字追加渲染
  onChunk: (text) => {
    const dom = document.getElementById('answer');
    dom.innerText += text;
  },
  onEnd: () => console.log('回答生成完毕'),
  onError: () => console.log('连接异常')
});

// 用户中断输出
// stream.stop()

2. WebSocket 适用场景(双向实时互通)

核心特点:独立 ws 协议,前后端随时互相发消息,支持二进制 / 文本

  • 视频通话、实时聊天室、多人在线游戏、协同文档、直播间互动、实时监控面板
  • 需求:两边要持续双向交互:你发一句、对方立刻回,还要传音频 / 视频二进制流、高频实时指令
WebSocket 极简封装(双向通信,支持心跳、自动重连、分片)
复制代码
// wsStream.js 精简版,去掉冗余逻辑
export function createWSStream(url, handlers) {
  let ws = null;
  let reconnectTimer = null;
  const heartbeatInterval = 30000;
  let heartTimer = null;

  // 发送心跳
  const sendHeartbeat = () => ws?.readyState === 1 && ws.send(JSON.stringify({ type: 'ping' }));
  // 销毁连接
  const destroy = () => {
    clearTimeout(reconnectTimer);
    clearInterval(heartTimer);
    ws?.close();
  };

  // 初始化连接
  function connect() {
    destroy();
    ws = new WebSocket(url);

    ws.onopen = () => {
      heartTimer = setInterval(sendHeartbeat, heartbeatInterval);
      handlers.onOpen?.();
    };

    ws.onmessage = (e) => {
      const msg = JSON.parse(e.data);
      // 心跳响应忽略
      if (msg.type === 'pong') return;
      // 流式分片
      if (msg.type === 'stream/text') {
        handlers.onChunk?.(msg.data);
        msg.isEnd && handlers.onEnd?.();
      }
    };

    ws.onclose = () => {
      handlers.onClose?.();
      // 指数退避重连
      reconnectTimer = setTimeout(connect, 2000);
    };

    ws.onerror = () => handlers.onError?.();
  }

  // 主动发送消息
  const send = (data) => {
    if (ws.readyState === WebSocket.OPEN) ws.send(JSON.stringify(data));
  };

  connect();
  return { send, destroy };
}

WS 使用示例(逐字渲染对话)

复制代码
const ws = createWSStream(`wss://xxx/ws/stream?token=xxx&sessionId=xxx`, {
  onChunk: (char) => {
    // 增量追加,逐字渲染
    const box = document.querySelector('.ai-text');
    box.textContent += char;
  },
  onEnd: () => console.log('流式完成'),
  onError: () => alert('连接断开,正在重试')
});

// 主动停止生成
ws.send({ type: 'stop_stream' });

// 页面卸载销毁
window.onbeforeunload = () => ws.destroy();
选型说明
  1. 仅 AI 流式输出、单向推送 → 用 SSE,代码更少、无需手动心跳、浏览器自带重连
  2. 需要双向交互(聊天、随时发指令停止、实时操作) → WebSocket

补充两个容易踩的小细节

  1. 为什么视频聊天不用 SSE? 视频音频是二进制数据流,而且需要双向传输(你传画面给对方,对方也传给你),SSE 只能后端单向下发,完全做不到上传本地音视频流。
  2. 特殊情况:有些 AI 客户端用 WebSocket 做对话 网页端大多 SSE,手机 App / 客户端很多用 WS。因为 App 需要长期保活、多轮连续对话双向收发,WS 双向通信更方便;网页只是单次提问流式回复,SSE 更轻量化、部署简单。

一句话记: 只需要后端源源不断吐文字 → SSE; 前后两边要频繁互发消息 / 传音视频二进制 → WebSocket。

相关推荐
小新讲网安15 分钟前
安全运营中心(SOC)建设实战:从SIEM到威胁狩猎全流程指南
网络·安全·web安全·网络安全·网安
SKYLAB0133 分钟前
打破智能家居生态壁垒|微喇智能 WKV553‑A 模组原生支持 Matter,解锁跨平台互联新体验
网络·智能家居
笨鸟先飞,勤能补拙2 小时前
Web 服务器与计算机网络全景原理
运维·服务器·前端·网络·人工智能·计算机网络·web安全
KindSuper_liu2 小时前
Unity 游戏网络基础:从 TCP、UDP 到 HTTP、TLS 与 Best HTTP
网络·游戏·unity
caimouse2 小时前
ReactOS 图形系统分析(3):显示驱动 DDI framebuf.dll
linux·运维·网络
M158227690552 小时前
四通道 Profinet 转 Modbus RTU 网关 SG-PN-Modbus_4 全场景落地详解
网络·工控布线
佳児素花痴╮2 小时前
网络问题与基础理论
运维·服务器·网络
Oflycomm2 小时前
IPC网络摄像机与安防监控:Wi-Fi 6模组、AOV低功耗与边缘AI的产业落地
网络·人工智能·安防监控·wifi6·ipc网络摄像机
0x532 小时前
Java网络编程(四)
java·网络
SendTomo3 小时前
跨设备文件互传新方案
javascript·网络·webrtc·html5·p2p