云计算百科
云计算领域专业知识百科平台

SSE服务器主动推送至浏览器客户端,让你不再需要websocket

Server-Sent Events(SSE)是一种服务器向客户端推送实时更新的技术,基于HTTP协议。客户端通过EventSource API来接收事件流,而服务器则保持一个长连接,持续发送数据。这与传统的请求-响应模式不同,允许服务器主动推送数据,而不是等待客户端请求。

客户端通过创建一个EventSource对象,指定服务器的URL。服务器设置特定的HTTP头(如Content-Type: text/event-stream)并保持连接打开。服务器可以周期性或根据事件发送数据,数据格式遵循SSE的规范,每条消息以"data: "开头,后跟数据内容,用两个换行结束。

然后,优缺点分析。优点是简单易用,基于HTTP,兼容性好,适合低频更新。缺点是单向通信,服务器到客户端,不支持客户端发送数据;同时,HTTP协议本身不是为长连接设计的,可能在某些情况下效率不如WebSocket。

适用场景包括实时新闻推送、股票行情更新、日志监控等不需要高频双向通信的场景。而如果应用需要高频通信或双向通信,WebSocket可能更合适。

最后,可能需要提到一些实现细节,比如数据格式、事件类型、重试机制等,以及如何在不同后端语言中实现SSE,比如java、PHP、Node.js等。

1. 工作原理

  • 客户端:通过 JavaScript 的 EventSource API 建立长连接
  • 服务端:设置 Content-Type: text/event-stream 响应头,保持连接持续打开
  • 通信方式:服务器按需发送文本数据流(UTF-8 编码),客户端自动解析

2. 核心优势

  • 轻量级:基于 HTTP 协议,无需复杂握手
  • 自动重连:内置断线重试机制
  • 兼容性佳:所有现代浏览器均支持
  • 简单实现:服务端只需保持长连接并发送文本流

3. 典型应用场景

  • 实时数据看板(如股票行情、系统监控)
  • 日志流实时查看
  • 通知推送系统
  • 协作工具中的实时更新

4. 与 WebSocket 对比

特性SSEWebSocket
通信方向 单向(服务器→客户端) 双向
协议 HTTP 独立协议
连接数 天然支持多标签页共享 需自行处理多连接
数据格式 文本流 二进制/文本
适用场景 低频更新 高频/双向通信

5. 最佳实践建议

  • 频率控制:建议至少间隔 1 秒发送数据,避免高频触发重绘
  • 数据压缩:使用 gzip 或 deflate 压缩传输内容
  • 错误处理:监听 onerror 事件并实现自动重连逻辑
  • 性能优化:结合 Last-Event-ID 实现断点续传
  • 安全退出:结束时发送空消息或特殊标识(如 data: END)

6. 代码示例

服务端源码

const express = require('express');
const app = express();
const port = 3000;

// 静态文件服务
app.use(express.static('public'));

// SSE路由
app.get('/events', (req, res) => {
// 设置SSE所需的头信息
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive'
});

// 发送初始消息
res.write('data: Connected to SSE server\\n\\n');

// 定时发送消息
let counter = 0;
const intervalId = setInterval(() => {
counter++;
const data = {
message: `Server time: ${new Date().toISOString()}`,
counter: counter
};
res.write(`data: ${JSON.stringify(data)}\\n\\n`);

// 模拟结束条件
if (counter >= 10) {
res.write('event: end\\ndata: Stream ended\\n\\n');
clearInterval(intervalId);
res.end();
}
}, 1000);

// 客户端断开连接时清理
req.on('close', () => {
console.log('Client disconnected');
clearInterval(intervalId);
res.end();
});
});

app.listen(port, () => {
console.log(`SSE server running at http://localhost:${port}`);
});

客户端H5页面端

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SSE Demo</title>
</head>
<body>
<h1>Server-Sent Events Demo</h1>
<div id="events"></div>

<script>
const eventSource = new EventSource('/events');
const eventsDiv = document.getElementById('events');

// 监听默认消息事件
eventSource.onmessage = function(e) {
const data = JSON.parse(e.data);
const p = document.createElement('p');
p.textContent = `${data.message} (Count: ${data.counter})`;
eventsDiv.appendChild(p);
};

// 监听自定义事件
eventSource.addEventListener('end', function(e) {
const p = document.createElement('p');
p.textContent = `Event: ${e.type}, Data: ${e.data}`;
eventsDiv.appendChild(p);
eventSource.close();
console.log('EventSource closed');
});

// 错误处理
eventSource.onerror = function(e) {
console.error('EventSource failed:', e);
eventSource.close();
};
</script>
</body>
</html>

7. 注意事项

  • 连接管理:确保在客户端断开连接时清理定时器和资源

  • 重连机制:SSE客户端会自动尝试重新连接

  • CORS:如果客户端和服务器不同源,需要设置CORS头

  • 性能考虑:对于大量客户端连接,考虑使用专门的解决方案如Redis PUB/SUB

  • 浏览器支持:大多数现代浏览器都支持SSE,但不包括IE

  • SSE 适用于大多数实时性要求不高的场景,如实时通知、股票行情、新闻推送等。其简洁性和兼容性使其成为轻量级实时通信的首选方案。对于需要双向通信或高频更新的场景,建议考虑 WebSocket 技术。

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » SSE服务器主动推送至浏览器客户端,让你不再需要websocket
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!