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。

相关推荐
酉鬼女又兒1 小时前
零基础入门计算机网络网际层核心:IP数据报发送与转发完整流程、静态路由配置方法、路由环路成因与解决方案及历年考研经典例题深度解析
网络·tcp/ip·计算机网络·考研·职场和发展
hyunbar7772 小时前
配置 Cloudflare Tunnel:把 Mac 上的 Web 服务变成安全域名
网络协议
qq_195821652 小时前
6. 应用层协议实现:CoE协议栈集成、对象字典配置、PDO映射
java·服务器·网络
程序猿零零漆2 小时前
Python核心进阶三连:闭包装饰器、深浅拷贝、网络编程从原理到实战
网络·python
袖手蹲2 小时前
K10 百炼 AI 语音助手从网络配置到全链路语音交互的嵌入式实战
网络·人工智能·交互
liulilittle2 小时前
KCC: An Exploration Along the Lines of BBR
网络·tcp/ip·计算机网络·bbr·通信·拥塞控制·kcc
星野爱8953 小时前
云顶之弈7周年新版本!手机随时随地畅玩周年时光机派对
网络·智能手机·电脑
AI科技星3 小时前
第六卷:量天尺传奇(几何学)
网络·人工智能·算法·概率论·学习方法·几何学·拓扑学
酉鬼女又兒3 小时前
零基础入门IPv4地址:从基本概念、分类编址、子网划分到无分类编址与应用规划全解
网络·网络协议·计算机网络·考研·职场和发展·分类·智能路由器