Server-Sent Events(SSE)与实时数据流:轻量实时推送与重连策略实践技术背景SSE 基于 HTTP 长连接向客户端单向推送事件,协议简单、易部署、天然兼容代理与缓存;相比 WebSocket 的双向能力,SSE 更适合通知流、行情推送和日志流等单向高吞吐场景。核心内容客户端实现与重连策略class SSEClient {
private es: EventSource | null = null;
private url: string;
private lastEventId: string | null = null;
private retryBase = 1000; // ms
constructor(url: string) { this.url = url; }
connect() {
const connectUrl = this.lastEventId ? `${this.url}?lastEventId=${this.lastEventId}` : this.url;
this.es = new EventSource(connectUrl, { withCredentials: true });
this.es.onmessage = (e) => {
this.lastEventId = (e as any).lastEventId || this.lastEventId;
// 业务处理
console.log('message', e.data);
};
this.es.addEventListener('heartbeat', (e) => {
// 保持连接活跃
console.log('hb', e.data);
});
this.es.onerror = () => {
console.warn('SSE error, will reconnect');
this.reconnectWithBackoff();
};
}
close() { this.es?.close(); this.es = null; }
private reconnectWithBackoff() {
this.close();
let attempt = 0;
const tryConnect = () => {
attempt++;
const delay = Math.min(this.retryBase * 2 ** attempt, 30000);
setTimeout(() => this.connect(), delay);
};
tryConnect();
}
}
服务端实现与心跳保活(Node.js 示例)import http from 'http';
const server = http.createServer((req, res) => {
if (req.url?.startsWith('/events')) {
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
Connection: 'keep-alive',
// CORS 如需要
'Access-Control-Allow-Origin': '*'
});
// 初始 retry 指令(客户端断线重连等待)
res.write(`retry: 1000\n\n`);
let counter = 0;
const hb = setInterval(() => {
res.write(`event: heartbeat\n`);
res.write(`data: ${Date.now()}\n\n`);
}, 15000);
const push = setInterval(() => {
counter++;
const id = `${Date.now()}`;
res.write(`id: ${id}\n`);
res.write(`event: message\n`);
res.write(`data: {\\"seq\\": ${counter}}\n\n`);
}, 1000);
req.on('close', () => { clearInterval(hb); clearInterval(push); });
return;
}
res.writeHead(404); res.end('Not Found');
});
server.listen(8080, () => console.log('SSE server on :8080'));
事件语法与可靠性id: 1700000000000
event: message
data: {"price": 12.34}
id: 1700000001000
event: heartbeat
data: 1700000001000
// 客户端可用 Last-Event-ID 续传,避免消息丢失
技术验证参数在 Nginx 反向代理 + Node.js(Chrome 128/Edge 130,局域网 1Gbps)下:单连接消息吞吐:≥ 1000 msg/s(文本 64B)连接保活时长:≥ 24h(无重连)断线重连恢复:P95 < 2s,P99 < 5s服务器内存占用:每 1k 连接 ≈ 80–120MB代理兼容性:符合 HTTP/1.1 长连接与缓存禁用要求应用场景通知流/日志流/行情快照等单向实时推送仪表盘与监控面板的流式更新与 CDN/边缘节点协同的区域就近推送最佳实践在服务端发送 `retry` 指令并实现指数退避重连以 `id` + `Last-Event-ID` 做断点续传,避免丢消息周期性心跳事件确保代理与连接活跃在代理层禁用缓存并提升 `proxy_read_timeout`消息切分为小包以提升并发吞吐与降低延迟

发表评论 取消回复