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。

相关推荐
M158227690552 小时前
跨协议互通利器|SG-PN-EIP (S)-220 Profinet 转 EtherNet/IP 网关,打通欧美 PLC 通讯壁垒
网络·网络协议·tcp/ip
北龙云海3 小时前
案例分享 | 面向公网业务系统境内访问白名单配置实操方案
运维·网络·安全·网络安全·告警·数据泄露·入侵攻击
闲猫4 小时前
Spring AI对接Deepseek 使用Charles代理api.deepseek.com 拦截报文,查看Tool和Skill的本质
网络·网络协议·http
niaiheni6 小时前
Fastjson 1.2.83 “Gadget-Free“ RCE
网络·安全·web安全
意疏6 小时前
远程办公软件哪个安全性高?UU远程8项安全防线全覆盖
网络·安全
牛马之星6 小时前
气体涡轮流量计如何维护
网络·经验分享
MonolithIoT6 小时前
实战方案|设备备件无人值守仓库:连续化产线运维备件 7×24 小时数字化管控方案
运维·网络·数据库
三8448 小时前
BGP/GRE练习
网络
念恒123069 小时前
网络基础
linux·网络·c++
白山云北诗9 小时前
漏洞扫描+渗透测试:从资产摸底到风险验证,完成二次安全收口
网络·安全·web安全·渗透测试·漏洞扫描·ddos防护·cc防护