JavaScript Server-Sent Events (SSE) 教程
JavaScript Server-Sent Events (SSE) 教程
1. SSE 简介
Server-Sent Events (SSE) 是一种允许服务器单向向客户端推送实时数据的 Web 技术。与 WebSocket 不同,SSE 是单向通信,专注于服务器向客户端发送数据流。
主要特点
- 基于 HTTP 协议
- 服务器单向推送数据
- 自动重连机制
- 轻量级
- 适合实时更新场景
2. 客户端 JavaScript 实现
基本使用方法
// 创建 EventSource 对象
const eventSource = new EventSource('/stream-endpoint');
// 监听消息事件
eventSource.onmessage = (event) => {
console.log('收到新消息:', event.data);
};
// 连接成功事件
eventSource.onopen = (event) => {
console.log('连接已建立');
};
// 错误处理
eventSource.onerror = (error) => {
console.error('EventSource 发生错误:', error);
eventSource.close(); // 手动关闭连接
};
自定义事件类型
const eventSource = new EventSource('/custom-events');
// 监听特定类型事件
eventSource.addEventListener('userUpdate', (event) => {
const userData = JSON.parse(event.data);
updateUserInterface(userData);
});
eventSource.addEventListener('systemAlert', (event) => {
showSystemNotification(event.data);
});
3. 服务器端实现 (Node.js Express 示例)
基本 SSE 服务器
const express = require('express');
const app = express();
app.get('/stream', (req, res) => {
// 设置 SSE 头部
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-open'
});
// 定期发送事件
const intervalId = setInterval(() => {
const data = {
timestamp: Date.now(),
message: '实时数据更新'
};
res.write(`data: ${JSON.stringify(data)}\n\n`);
}, 1000);
// 客户端断开连接时清理
req.on('close', () => {
clearInterval(intervalId);
});
});
自定义事件流
app.get('/custom-stream', (req, res) => {
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache'
});
// 发送不同类型的事件
res.write(`event: userUpdate\n`);
res.write(`data: ${JSON.stringify({id: 1, name: '张三'})}\n\n`);
res.write(`event: systemAlert\n`);
res.write(`data: 系统维护通知\n\n`);
});
4. 高级用法和最佳实践
重连策略
const eventSource = new EventSource('/stream');
// 自定义重连间隔
eventSource.reconnectInterval = 5000; // 5秒重试
// 指数退避重连策略
function exponentialBackoff(attempt) {
return Math.min(30000, Math.pow(2, attempt) * 1000);
}
错误处理和恢复
let reconnectAttempts = 0;
eventSource.onerror = (error) => {
console.error('连接错误', error);
if (eventSource.readyState === EventSource.CLOSED) {
// 使用指数退避重连
const delay = exponentialBackoff(reconnectAttempts++);
setTimeout(() => {
eventSource = new EventSource('/stream');
}, delay);
}
};
5. 兼容性和限制
浏览器兼容性
- 现代浏览器(Chrome, Firefox, Safari, Edge)支持良好
- Internet Explorer 不支持
- 移动浏览器支持情况较好
限制
- 单向通信
- 每个浏览器对并发 SSE 连接数有限制
- 长时间运行可能需要额外的服务器配置
6. 使用场景
- 股票价格实时更新
- 社交媒体动态推送
- 实时通知系统
- 日志和监控流
- 游戏状态同步
7. 安全注意事项
- 使用 HTTPS 保护数据传输
- 实现服务器端身份验证
- 限制事件流的大小和频率
- 防止大量并发连接
结论
Server-Sent Events 提供了一种简单、高效的方式实现服务器到客户端的实时通信。相比 WebSocket,它更轻量、更专注于单向数据推送。