我们使用AI时AI对我们说的话不会一次性把全部内容弹出来而是会像流水一样一点点吐出来那么这种丝滑的交互体验背后的核心就是SSE (Server-Sent Events)。什么是 SSESSEServer-Sent Events服务器发送事件是一种基于 HTTP 协议的通信技术它允许服务器在有新数据时主动且持续地将数据“推”送到客户端通常是浏览器。简单来说SSE 是实现“流式输出”的一种标准协议。如果把“流式输出”比作信息传递的模式SSE 就是实现这一模式的具体通信方案。SSE 的前世今生SSE 最初由 HTML5 标准的主要编辑者伊恩·希克森Ian Hickson定义。它的出现是为了解决传统 Web 通信在实时性上的痛点。SSE 的历史可以追溯到 2004 年左右它的发展经历了以下几个阶段Opera 软件公司提出原型最早由 Opera 浏览器公司在 2004 年提出当时名为“Server-Sent DOM Events”。其初衷是希望浏览器能有一种比“轮询Polling”更高效的方式来获取服务器数据。纳入 HTML5 草案随后这项技术被纳入了正在制修订的HTML5 标准之中。W3C 与 WHATWG 标准化WHATWG网页超文本应用技术工作小组负责 HTML 生活标准Living Standard的维护。W3C万维网联盟曾将其作为独立的 API 规范进行管理。为什么在 SSE 出现之前很痛苦在 SSE 之前网页要获取服务器的实时更新只能依靠轮询 (Polling)浏览器每隔几秒问一次服务器“有新消息吗”这极大地浪费带宽和 CPU。长轮询 (Long Polling)服务器挂起请求直到有数据才返回。虽然效率略高但每次连接仍需重新握手开销巨大。SSE 的诞生正是为了提供一种轻量、高效、基于 HTTP 的单向实时通信方案完美规避了轮询的弊端。SSE 的核心工作原理SSE 建立的是一个单向的通信通道。其流程如下客户端发起请求浏览器发送一个普通的 HTTP 请求并在 Header 中设置Accept: text/event-stream。服务器保持连接服务器不立即关闭请求而是将响应头Content-Type设置为text/event-stream并保持该 HTTP 连接。持续推送一旦有新数据例如 AI 生成的新 Token服务器便按照 SSE 规定的格式源源不断地发送数据块。SSE 的数据格式规范为了保证传输的稳定性SSE 要求传输的数据必须是纯文本且遵循特定的行格式data:开头后接实际内容。\n\n结尾两个换行符表示一条消息的结束。可选字段支持id:用于断线重连或event:定义自定义事件。标准示例data: {content: 你}data: {content: 好}data: [DONE]SSE 和 WebSocketSSE 和 WebSocket的区别维度SSEWebSocket通信方向单向服务器 - 客户端双向全双工协议基础HTTPHTTP 升级协议开发难度低浏览器原生支持高需要复杂握手/管理防火墙友好非常好HTTP 长连接有时会被代理拦截为什么 AI 聊天都选 SSE核心原因在于“简单即是力量”。AI 对话通常是客户端发问服务器流式返回SSE 这种轻量化的 HTTP 协议完全满足需求无需额外的复杂配置且在防火墙穿透性上更有优势。SSE 就像是专门用来发送流水线货物的“传送带”。当我们需要将一份完整的数据像挤牙膏一样一点点运送给用户时SSE 是目前最标准、最易用的选择。使用 FastAPI 实现 SSEfrom fastapi import FastAPI from fastapi.responses import StreamingResponse import asyncio app FastAPI() async def event_generator(): words [天, 气, 真, 好, 呀] for word in words: # 必须严格遵守 data: 内容 \n\n 的格式 yield fdata: {word}\n\n await asyncio.sleep(0.5) # 模拟 AI 生成的延迟 yield data: [DONE]\n\n app.get(/stream) async def stream(): return StreamingResponse(event_generator(), media_typetext/event-stream)