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。

相关推荐
tuddy78946413 分钟前
Privazer 源码级避坑指南:从编译到部署的深度解析
网络·copilot
懒鸟一枚19 分钟前
Linux 系统 Service 服务配置详解
linux·服务器·网络
无名38735 分钟前
RTCPtype
网络
techdashen1 小时前
从网络栈继续往下:micro:bit、2.4GHz、调制方式,以及一个不太靠谱但很有趣的想法
网络·fpga开发
碎碎念_4922 小时前
网络通信基础:IP协议、ARP协议、DHCP
网络·arp·dhcp·ip协议
Geeys2 小时前
淘宝电商运营新手入门完整教程|零基础开店引流
大数据·网络·人工智能
子不语1802 小时前
从0开始学习S7-1200+ET200SP(3)——两台S7-1200通过TCP连接
网络协议·学习·tcp/ip
折哥的程序人生 · 物流技术专研2 小时前
Java面试通关⑦:JavaWeb网络核心全集
网络协议·http·javaweb·校招·前后端交互·java面试·社招
FlightYe2 小时前
FFmpeg移动端硬解机制
linux·网络·ffmpeg·音视频·实时音视频·视频编解码
huainingning3 小时前
锐捷ACL单向TCP互通组网-通过Established状态回包实现
服务器·网络·tcp/ip