Server-sent Events(SSE)是在 HTML5 中引入的一项新技术,它允许服务端在任意时刻向客户端推送数据。与传统的 HTTP 请求不同,SSE 建立了一条持久的连接,允许服务端随时向客户端推送数据。本文将深入介绍 SSE 的原理、实现和应用,以及如何使用它在前端中实现实时数据推送。
原理
SSE 基于 HTTP 协议,使用了长链接(long-polling),因此支持异步服务器推送。客户端通过建立一条与服务器的长链接,不断地接收来自服务器的数据流。服务器将数据流按照 SSE 规范封装成一条条事件(Event),客户端感知到接收到事件后,便可以对事件做出相应的处理。根据 SSE 规范,一个事件可以包含以下三种信息:
- 事件标识符:定义事件的类型,客户端可以根据不同类型的事件做出不同的处理。
- 事件数据:服务器要推送给客户端的数据。
- 事件注释:客户端不会处理的任何其他信息。注释可以帮助客户端了解事件的背景和用途。
例如,下面是一个基本的 SSE 事件:
event: eventType data: event data
其中 eventType
是事件标识符,event data
是事件数据。事件以 event:
开头,后面接事件标识符,以 data:
开头,后面接事件数据。事件可以由多个行组成,每个行都必须以 \n
结尾。事件以两个空行(\n\n
)结尾。
实现
在服务器端,要实现 SSE 只需要满足以下几个条件:
- 按照 SSE 规范输出数据。
- 使用
Content-Type: text/event-stream
设置响应头。 - 使用
Cache-Control: no-cache
禁用缓存。
在 Node.js 中,可以使用 res.write()
和 res.flush()
实现 SSE。下面是一个基本的 Node.js SSE 示例:
// javascriptcn.com 代码示例 const http = require('http'); http.createServer((req, res) => { res.writeHead(200, { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', }); setInterval(() => { const data = Math.random(); res.write(`event: random\ndata: ${data}\n\n`); res.flush(); }, 1000); }).listen(8080);
在客户端,可以使用 EventSource
对象订阅 SSE。EventSource
对象会自动处理 SSE 协议,并根据事件标识符将事件转发到相应的处理器中。下面是一个基本的 SSE 客户端示例:
const eventSource = new EventSource('http://localhost:8080/'); eventSource.addEventListener('random', event => { console.log(event.data); });
应用
SSE 能够实现实时数据推送,因此其应用场景主要是在需要实时通知客户端数据更改的场合。例如:
- 股票行情:当股票价格变动时向客户端推送最新价格。
- 网络游戏:向客户端推送其他玩家位置信息和游戏状态。
- 实时聊天:向客户端推送其他用户发送的聊天消息。
此外,SSE 在实现比 Ajax 更简单,并且能够在客户端保持连接的情况下节省服务器资源。
总结
SSE 是一种基于 HTTP 的实时数据推送技术,可以用于实现实时通知和数据推送。其原理是通过建立一个长连接,让客户端不断地接收来自服务器的数据流。在服务器端,只需要按照 SSE 规范封装数据流并设置响应头即可。在客户端,可以通过 EventSource
对象订阅 SSE,并处理服务器推送的事件。
参考文献:
- MDN Web Docs. Server-sent Events [EB/OL]. https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events, 2021-05-31.
- SSE Tutorial [EB/OL]. https://www.html5rocks.com/en/tutorials/eventsource/basics/, 2021-05-31.
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6502a53995b1f8cacdfe1ae9