打字机效果通常是通过 SSE 实现的,请说下 SSE 和 WebSocket 的区别?

1 阅读3分钟

在 AI 问答场景中,选择 SSE 而不是 WebSocket,主要是因为 AI 回答是典型的单向数据流场景。SSE 基于 HTTP 协议,实现简单,且浏览器原生支持断线重连,能够以最低的开发成本实现类似 ChatGPT 的打字机效果。而 WebSocket 更适合需要高频双向互动的场景,比如即时通讯软件。

核心区别:

  • SSE (Server-Sent Events)单向通信。服务器只能往客户端推数据,客户端只能听。基于 HTTP 协议。
  • WebSocket双向通信。服务器和客户端可以随时互发消息。基于 TCP 的独立协议(ws:// 或 wss://)。

协议与握手

  • SSE

    • 基于标准 HTTP 协议。
    • 请求头中包含 Accept: text/event-stream
    • 连接建立后,响应头为 Content-Type: text/event-stream,连接保持打开。
    • 优点:天然支持 HTTP 的各种特性(如认证、Cookie、代理服务器),无需额外配置。
  • WebSocket

    • 需要进行 HTTP 升级握手。
    • 请求头包含 Upgrade: websocket 和 Connection: Upgrade
    • 握手成功后,协议从 HTTP 切换为 WebSocket 协议。
    • 缺点:在某些严格的防火墙或代理服务器下,可能会拦截非 HTTP 协议的流量,配置相对复杂。

断线重连(前端开发最关心的点)

  • SSE原生支持断线重连

    • 浏览器的 EventSource API 自带重连机制。连接断开后,浏览器会自动尝试重新连接。
    • SSE 还支持发送 Last-Event-ID,服务器可以据此实现断点续传(告诉服务器我上次收到哪条消息了)。
  • WebSocket不支持自动重连

    • 断线后,前端开发者必须自己写心跳检测逻辑和重连逻辑(这也是很多面试官会追问的点:“怎么保证 WebSocket 连接不断?”)。

数据格式与开销

  • SSE

    • 只能传输 UTF-8 文本。如果要传二进制,需要编码。
    • 数据格式有特定规范,开销相对较大一点。
  • WebSocket

    • 支持文本和二进制数据
    • 数据帧非常轻量,头部开销极小(2~10 字节),传输效率极高。

AI 问答场景(打字机效果)首选 SSE

原因有三点:

  1. 业务模型契合(单向输出)
    AI 对话的模型是:用户发一个问题 -> AI 流式输出答案。
    在 AI 回答的过程中,用户通常不需要再发新指令(或者即使发了,也开启新的一轮对话)。这是一个典型的请求-响应流模型,SSE 的单向通信完全满足,杀鸡焉用牛刀。
  2. 简单易用,工程成本低
    SSE 是基于 HTTP 的。前端用 EventSource 或 fetch,后端用普通的 Web 框架(Node.js, Python Flask/FastAPI 等)只需设置特殊的 Header 即可。
    不需要像 WebSocket 那样维护复杂的连接状态管理、心跳机制。
  3. 断点续传与错误恢复
    AI 生成长文本可能耗时很久。如果网络波动,SSE 的自动重连和 Last-Event-ID 机制能更好地让用户看到“续接”的内容,体验更好。