基于 HTTP 的单向流式通信协议SSE详解

SSE(Server-Sent Events)详解

🧠 什么是 SSE?

SSE(Server-Sent Events) 是 HTML5 标准中定义的一种通信机制,它允许服务器主动将事件推送给客户端(浏览器)。与传统的 HTTP 请求-响应不同,SSE 是一种基于 HTTP 的单向流式通信协议。

📌 核心特性

特性 描述
通信方式 单向:服务器 → 客户端
连接类型 持久的 HTTP 长连接
数据格式 文本(MIME 类型:text/event-stream)
自动重连 浏览器自动支持
底层协议 HTTP/1.1,兼容 HTTP 代理、缓存、身份验证
建立方式 浏览器端使用 EventSource 对象

🧱 通信流程(架构图)

text 复制代码
浏览器(客户端)
└── 发起 HTTP GET 请求(Accept: text/event-stream)
    ↓
服务器端(保持连接)
└── 每当有事件,推送:
    data: xxx
    id: 1
    event: myEvent
    retry: 3000

[连接不断,服务器持续发送,客户端持续接收]

🧪 示例详解

1. 客户端(JS)

javascript 复制代码
const source = new EventSource('/events');

source.onmessage = (event) => {
  console.log('默认消息:', event.data);
};

source.addEventListener('update', (event) => {
  console.log('收到 update 事件:', event.data);
});

source.onerror = (err) => {
  console.error('连接异常', err);
};

2. 服务器端(Node.js 示例)

js 复制代码
app.get('/events', (req, res) => {
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Cache-Control', 'no-cache');
  res.setHeader('Connection', 'keep-alive');

  res.write('retry: 5000\n'); // 自动重连时间
  res.write('event: update\n');
  res.write(`data: 你好,客户端\n\n`);

  const interval = setInterval(() => {
    res.write(`data: 当前时间 ${new Date().toISOString()}\n\n`);
  }, 3000);

  req.on('close', () => {
    clearInterval(interval);
    res.end();
  });
});

🎯 典型应用场景

场景 描述
实时通知系统 消息推送、任务进度提醒
实时监控面板 日志、CPU、内存、API 状态
数据大屏 股票/气象/新闻流更新
聊天室(只读方) 只需服务器广播消息
DevTools/日志监听 构建日志实时显示

📄 SSE 消息格式

text 复制代码
event: update
id: 12345
retry: 5000
data: 你好
data: 世界

字段说明

字段 说明
data: 消息内容,可多行,客户端拼接为一条
event: 事件名称,配合 JS 的 addEventListener 使用
id: 消息 ID,客户端会自动缓存用于断线续传
retry: 告诉浏览器下次重连时间(ms)

🧰 与 WebSocket 对比

对比项 SSE WebSocket
通信方向 单向(服务器 → 客户端) 双向
协议 基于 HTTP 使用 ws:// 或 wss://(非 HTTP)
使用复杂度 简单(浏览器原生支持) 需要手动管理消息格式、连接状态
数据格式 纯文本(text/event-stream) 文本或二进制
自动重连 浏览器原生支持 需要自行实现
代理支持 很好(HTTP 代理可用) 差(很多 HTTP 代理不支持)
应用场景 实时通知、日志流 聊天、游戏、协同操作等交互频繁的场景

📡 浏览器支持情况

浏览器 支持情况
Chrome ✅
Firefox ✅
Safari ✅
Edge(Chromium) ✅
Internet Explorer ❌ 不支持
移动端浏览器 ✅(多数现代浏览器)

⚠️ 限制与注意事项

  1. 不支持 IE
  2. 只能从服务器推送
  3. 受限于 HTTP 连接数
  4. 不适合传输大量二进制数据

🔐 跨域 & 认证

  • 使用 CORS 即可跨域支持:
text 复制代码
Access-Control-Allow-Origin: *
Content-Type: text/event-stream
  • URL Token 示例:
js 复制代码
new EventSource(`/events?token=abc123`);

📦 框架与工具支持

技术栈 支持方式
Node.js 原生、Express、NestJS
Python Flask + flask-sse,Django Channels
Java Spring WebFlux、Servlet 推送
Go 原生 net/http
Rust Actix、Rocket 支持 SSE
Vue/React 用 EventSource 封装 Hook/Composables
Nginx 可代理 SSE,需关闭缓存,配置 proxy_buffering off;

✅ 总结:SSE 的优势与应用判断

  • ✅ 简单、轻量级、易于实现和部署(基于 HTTP)
  • ✅ 适合实时监控、系统通知、数据流更新
  • ❌ 不适合需要客户端发消息或二进制传输
  • ❌ 兼容性上需考虑 IE 或企业内网浏览器情况
相关推荐
默|笙10 小时前
【Linux网络】传输层协议TCP(3)滑动窗口、流量控制
linux·网络·tcp/ip
xiaoye-duck10 小时前
《C++ 项目:手写大模型接入 SDK》ChatGPT接口设计(中):全量响应实现和测试
网络·c++·语言模型·chatgpt
无言听风雨丶12 小时前
systemd 与信号 / 僵尸进程:Linux 进程管理的底层逻辑与排错
linux·服务器·网络
小贾要学习12 小时前
【C++后端开发项目】Reactor 模型 / C++ 仿写 muduo HTTP 服务器:让底层网络库真正跑起网页
linux·服务器·c++·http·网络编程·muduo·reactor模型
g5zhu589612 小时前
没有公网ip的情况下,本地能ping服务器服务器不能ping本地,让服务器能访问本地某端口的简单方法
服务器·网络协议·tcp/ip
SDWAN_Cheap12 小时前
BGP是什么,广播IP是什么?两个容易混淆的概念拆解
网络·tcp/ip·bgp·广播ip
程序员JerrySUN12 小时前
PCIe Gen5 SSD 为什么读得快、写得慢?从存储原理到 Linux 性能实测
linux·服务器·网络
guizhoumen13 小时前
net core下WebSocket请求总是断开的解决方案
网络·websocket·网络协议
HKT_China13 小时前
香港电讯河套区创新科技中心暨AI机楼揭幕,以网络基建助力北部都会区发展
网络·ai
云边云科技_云网融合13 小时前
案例分享 | 某运动零售品牌多云治理实战:一套框架解决权限失控、网络混乱与成本黑箱
网络·零售