SSE 入门

文章目录

    • [1. 工作原理:一个永不结束的 HTTP 响应](#1. 工作原理:一个永不结束的 HTTP 响应)
      • [1.1 建立流程](#1.1 建立流程)
      • [1.2 SSE 协议数据格式](#1.2 SSE 协议数据格式)
    • [2. 核心特点](#2. 核心特点)
      • [2.1 优点](#2.1 优点)
      • [2.2 缺点](#2.2 缺点)
    • [3. 重连机制详解](#3. 重连机制详解)
      • [3.1 默认重连行为](#3.1 默认重连行为)
      • [3.2 服务端控制重连间隔](#3.2 服务端控制重连间隔)
    • [4. 断点续传实现](#4. 断点续传实现)
      • [4.1 工作原理](#4.1 工作原理)
    • [5. 与 WebSocket 的选型对比](#5. 与 WebSocket 的选型对比)
      • [5.1 对比表格](#5.1 对比表格)
      • [5.2 选型建议](#5.2 选型建议)

SSE (Server-Sent Events) 是一种基于 标准 HTTP 协议 的服务器主动推送技术。它允许服务器通过一个 长连接 持续向客户端发送数据流,客户端使用浏览器内置的 EventSource API 即可接收。

SSE 核心原理

客户端发起一个普通的 HTTP 请求,服务端收到后不关闭连接 ,而是将响应头 Content-Type 设置为 text/event-stream。每当有新数据时,服务端按协议格式写入响应流,客户端通过监听事件实时接收。连接保持打开状态,直到任意一方主动关闭或网络中断

SSE 是单向的:服务器 → 客户端。客户端若需发送数据,需要另外发起一个普通的 HTTP 请求

1. 工作原理:一个永不结束的 HTTP 响应

SSE 的建立非常简单,没有复杂的握手升级过程:

1.1 建立流程

  1. 客户端发起请求new EventSource('/api/stream')
  2. 服务器响应 :返回状态码 200,并设置以下响应头
    • Content-Type: text/event-stream
    • Cache-Control: no-cache
    • Connection: keep-alive
  3. 数据推送:服务端保持连接打开,按 SSE 协议格式不断写入数据块
  4. 连接关闭:服务端或客户端主动关闭,或网络断开

1.2 SSE 协议数据格式

每条消息由若干字段组成,字段之间用 \n 分隔,消息之间用 两个换行符 \n\n 结尾。

字段说明

字段 含义 是否必须 说明
event: 事件类型 默认触发 onmessage,可自定义如 updateerror
data: 数据内容 可多行,客户端会自动拼接
id: 消息唯一标识 用于断线续传,重连时会带到 Last-Event-ID
retry: 重连等待时间(ms) 覆盖浏览器默认的 3 秒重连间隔

示例消息

复制代码
event: message
id: 1001
data: {"type": "text", "content": "Hello"}
data: 这是第二行内容,会与上一行拼接

注意:最后必须有 两个换行符 表示消息结束。

2. 核心特点

2.1 优点

特点 说明
简单轻量 基于标准 HTTP,无需特殊协议,任何 Web 服务器都能支持
自动重连 浏览器内置 EventSource 会在连接断开后自动重连,无需手动实现
断点续传 通过 id 字段和 Last-Event-ID 机制,服务端可恢复丢失的消息
低开销 相比 WebSocket,没有复杂的握手和帧协议,Header 开销极小
天然跨域友好 支持 CORS,可通过 withCredentials 配置携带凭证
调试方便 本质是 HTTP 请求,可在浏览器 DevTools Network 面板直接查看

2.2 缺点

缺点 说明
单向通信 只能服务器推送给客户端,客户端需要另外发 HTTP 请求上传数据
连接数限制 HTTP/1.1 下浏览器对同一域名的长连接数有限制(通常 6 个)
二进制支持弱 原生只支持文本(UTF-8),二进制需用 Base64 编码传输
IE 不支持 IE 全系列不支持,Edge 及所有现代浏览器均已支持
服务端需维护长连接 每个连接都占用服务端资源,高并发时需注意

3. 重连机制详解

SSE 最大的优势之一就是浏览器内置了自动重连,无需手动实现复杂的重试逻辑。

3.1 默认重连行为

  • 连接断开后,浏览器会等待 3 秒 后自动尝试重连
  • 重连时会自动携带上次收到的最后一条消息的 id,放在 Last-Event-ID 请求头中
  • 服务端可根据这个 ID 决定从哪个位置开始续传
  • 重连会无限进行下去,直到连接成功或客户端主动关闭

3.2 服务端控制重连间隔

服务端通过发送 retry 字段可以覆盖客户端的重连等待时间:

复制代码
retry: 5000

注意:retry 字段单独占一行,前后不需要 data:。服务端可以在任意时刻发送,客户端收到后立即生效。

4. 断点续传实现

SSE 协议原生支持断点续传,核心是 id 字段和 Last-Event-ID 请求头。

4.1 工作原理

  1. 服务端每条消息带一个唯一的、单调递增的 id
  2. 客户端收到消息后,浏览器自动记录最后一条的 id
  3. 连接断开后,浏览器重连时自动在请求头中携带 Last-Event-ID
  4. 服务端读取这个头,从该 ID 的下一条开始推送

5. 与 WebSocket 的选型对比

5.1 对比表格

特性 SSE WebSocket
通信方向 单向(服务器 → 客户端) 双向(服务器 ↔ 客户端)
协议 标准 HTTP (http:// / https://) 独立协议 (ws:// / wss://)
重连机制 浏览器内置自动重连 需要手动实现
断线续传 原生支持 (id + Last-Event-ID) 需要自行设计
二进制数据 需 Base64 编码 原生支持
连接数限制 HTTP/1.1 有限制,HTTP/2 可解决 无明显限制
实现复杂度
调试难度 低(HTTP 请求可见) 中(需要专门工具)
服务端压力 维护 HTTP 长连接 维护更复杂的协议状态

5.2 选型建议

场景 推荐方案 理由
AI 大模型流式输出 SSE 单向推送,实现简单,自动重连
实时监控大屏/行情看板 SSE 大量只读客户端,服务端负担轻
新消息提醒/订单状态通知 SSE 够用且简单,开发成本低
即时聊天/IM WebSocket 需要频繁双向交互
协同编辑(如 Google Docs) WebSocket 需要双向实时同步
在线游戏 WebSocket 极低延迟 + 双向二进制数据
需要兼容 IE WebSocket 或 轮询 IE 不支持 SSE
相关推荐
云计算磊哥@43 分钟前
运维开发宝典023-WEB网站服务
运维·前端·运维开发
加点油。。。。1 小时前
【1.Obsidian渲染html文件】
前端·html·obsidian
ZFSS1 小时前
BYOK(自带密钥)使用指南
运维·服务器·前端·人工智能·midjourney
AI_零食1 小时前
呼吸灯 - 通过鸿蒙PC Electron框架技术完成-在焦虑时代守护每一次呼吸的数字禅修
前端·javascript·华为·electron·前端框架·鸿蒙
佛山个人技术开发1 小时前
高端旅游风景区酒店民宿网站模板 自适应宽屏文旅酒店源码
前端·html5·旅游
ZC跨境爬虫1 小时前
跟着 MDN 学JavaScript day_5:技能测试——变量实战
java·开发语言·前端·javascript
pan_junbiao2 小时前
Whistle 抓包工具的安装与使用
前端·测试工具·压力测试·抓包
Cory.眼2 小时前
前端调用后端接口全流程实战
前端·调用接口
牛栓柱2 小时前
【后端实战】用 Supabase + React/TS 零成本构建高并发 Multi-Agent 服务
前端·数据库·人工智能·后端·react.js·前端框架