在 Web 应用开发中,实时数据推送和展示是一项很重要的需求,如实时地图监控、实时聊天等等。实时数据推送技术分为两类:轮询和长连接。而 Server-sent Events (SSE) 是一种基于长连接的推送技术,被广泛应用于 Web 实时数据推送场景中。
什么是 Server-sent Events
SSE 是一种服务器向客户端推送数据的 HTML5 技术,它允许网页自动更新数据流。使用 SSE 可以轻松地实现实时数据推送,不需要像 WebSocket 一样进行协议升级,因为 SSE 是基于 HTTP 长连接的,而 HTTP 协议是已经被广泛支持的。
实现步骤
- 服务器端实现 SSE
使用 SSE 时,服务器端需要发送特定格式的数据流。数据流以 "data:" 前缀开头,后跟发送的数据,最后以两个换行符作为结尾。例如,下面是一条数据流:
data: {"id":1, "lng":116.403, "lat":39.915}\n\n其中的 "id" 是某个设备的 ID,"lng" 和 "lat" 分别表示纬度和经度。数据流格式是约定好的,需要按照规定的格式发送,否则客户端会无法解析。服务端实现也很简单,可以参考一下的示例代码:
// www.javascriptcn.com code example
// 服务端代码
const http = require('http');
// 发送数据流的函数
function sendEvent(response, eventData) {
const data = `data: ${JSON.stringify(eventData)}\n\n`;
response.write(data);
}
// 启动 HTTP 服务
const server = http.createServer((req, res) => {
// 常规的 HTTP 处理逻辑
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive'
});
setInterval(() => {
// 模拟 GPS 位置发生变化
const eventData = {
id: 1,
lng: 116 + Math.random(),
lat: 39 + Math.random()
};
sendEvent(res, eventData);
}, 1000);
}).listen(8080);
console.log('Server is started at http://localhost:8080');注意,返回的数据要以 "text/event-stream" 类型,并且添加 "Cache-Control" 和 "Connection" 头。由于 SSE 是基于 HTTP 长连接的,所以 Connection 头是必须的,它告诉客户端以长连接的方式获取实时数据。例如,Chrome DevTools 网络面板截图如下:
- 客户端实现 SSE
客户端可以使用 HTML5 中的 EventSource 对象来建立连接并接收数据流。下面是一个简单的 HTML 示例代码:
// www.javascriptcn.com code example
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>SSE Example</title>
</head>
<body>
<h1>实时地图监控</h1>
<div id="map"></div>
<script>
const eventSource = new EventSource('/sse');
eventSource.onmessage = (event) => {
const position = JSON.parse(event.data);
console.log(position); // 调试用
// 在地图上显示设备位置
// ...
};
</script>
</body>
</html>其中,"/sse" 是 SSE 服务端的 URL。在 "onmessage" 事件中处理返回的数据并更新地图显示。
指导意义
使用 SSE 技术可以轻松地实现 Web 实时数据推送功能,它比轮询技术有更低的资源消耗,并且比 WebSocket 更简单易用,在某些场景下可以替代 WebSocket。SSE 还可以结合 Service Worker 实现离线数据推送。因此,在开发 Web 实时数据交互场景时,可以优先考虑使用 SSE。
结语
本文介绍了 SSE 技术在实时地图监控中的应用,对于其他实时数据推送场景如聊天等同样适用。SSE 是一种十分实用的技术,它简单易用且性能好,建议在一些简单场景下尝试使用。完整示例代码详见 GitHub。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67d01101e46428fe9ec9bd8b