HTML5 SSE 服务器发送事件
Server-Sent Events (SSE) 是 HTML5 引入的服务器推送技术,允许服务器主动向客户端发送消息,实现单向实时通信。
简介
Server-Sent Events(SSE)是一种服务器向浏览器推送数据的技术。与 WebSocket 的全双工通信不同,SSE 是单向的——只有服务器可以向客户端发送消息,客户端无法通过 SSE 向服务器发送数据。
SSE 基于 HTTP 协议,使用持久连接,相比 WebSocket 更加轻量,特别适合股票行情、新闻推送、社交媒体更新等只需要服务器单向推送的场景。
基本用法
使用 EventSource API 接收服务器发送的事件:
创建 EventSource
// 检查浏览器支持
if (typeof(EventSource) !== "undefined") {
// 连接到 SSE 服务器
var source = new EventSource("/api/sse");
// 接收消息
source.onmessage = function(event) {
console.log("收到消息: " + event.data);
};
// 连接打开
source.onopen = function(event) {
console.log("连接已建立");
};
// 处理错误
source.onerror = function(event) {
console.error("连接错误");
};
// 关闭连接
source.close();
} else {
console.log("浏览器不支持 SSE");
}
自定义事件
SSE 支持发送自定义事件,客户端可以监听特定类型的事件:
监听自定义事件
// 监听名为 "news" 的事件
source.addEventListener("news", function(event) {
var data = JSON.parse(event.data);
console.log("新闻: " + data.title);
});
// 监听名为 "stock" 的事件
source.addEventListener("stock", function(event) {
var data = JSON.parse(event.data);
console.log("股票: " + data.symbol + " $" + data.price);
});
// 监听默认消息事件
source.onmessage = function(event) {
console.log("默认消息: " + event.data);
};
服务器端发送的事件格式:
服务器端事件格式
// 服务器响应格式
# 默认事件
data: {"message": "Hello"}
# 自定义事件
event: news
data: {"title": "重要新闻", "content": "..."}
# 带ID的事件
id: 1
event: stock
data: {"symbol": "AAPL", "price": 150.25}
# 重试间隔(毫秒)
retry: 5000
关闭连接
不再需要接收消息时,应该关闭 SSE 连接:
关闭 EventSource
// 关闭 SSE 连接
source.close();
// 关闭后尝试重新连接会被忽略
console.log(source.readyState); // 2 表示已关闭
SSE vs WebSocket
选择 SSE 还是 WebSocket 取决于具体需求:
| 特性 | SSE | WebSocket |
|---|---|---|
| 通信方向 | 单向(服务器→客户端) | 全双工(双向) |
| 协议 | HTTP/HTTPS | WebSocket (ws/wss) |
| 兼容性 | 除IE外都支持 | 所有现代浏览器 |
| 自动重连 | 支持 | 需要手动实现 |
| 适用场景 | 股票、新闻、通知 | 聊天、游戏、协作 |
注意事项
开发提示
- SSE 只支持 UTF-8 编码
- 每个浏览器对并发 SSE 连接数有限制(通常为6个)
- 服务器需要设置正确的 MIME 类型
text/event-stream - 使用 last-event-id 头可以实现断线重连后的消息补发
- SSE 不支持二进制数据,需要编码后传输