SSE(Server-Sent Events,又称为 EventSource)是一种浏览器与服务器之间的消息推送技术,它通过 HTTP 协议的长连接,实现了服务器端向客户端推送数据的能力。与 WebSocket 相比,SSE 更加轻量级和简单易用,可以在不需要双向通信的场景下,快速实现消息推送。
SSE 库原理
SSE 协议
SSE 协议是一种基于纯文本的协议,它以行为分割符,每行一条数据。需要注意的是,每条数据前必须加上 data:
,并以两个回车符结束,否则浏览器不会解析。例如,一条简单的 SSE 数据如下:
----- ----- -----
SSE API
SSE API 是浏览器端实现 SSE 的接口,它通常由 XMLHttpRequest 对象封装,提供了如下三个方法:
EventSource(url: string, options?: EventSourceInit): EventSource
创建一个 EventSource 对象,参数
url
是 SSE 服务地址,options
是一个可选对象,包含如下属性:withCredentials
:是否携带跨域凭证。headers
:HTTP 请求头信息。retryInterval
:尝试重新连接的时间间隔,单位为毫秒,默认为 3000ms。
EventSource.readyState: number
返回连接状态,共有三种:
- CONNECTING(0):连接正在建立。
- OPEN(1):连接已经建立成功。
- CLOSED(2):连接已经关闭。
EventSource.onmessage: (event: MessageEvent) => void
监听消息事件,当收到服务器推送的数据时,触发该回调函数。
MessageEvent
中包含如下属性:event.data
:SSE 推送的数据。event.lastEventId
:上一次接收数据时,服务器发送的事件 ID。event.origin
:SSE 服务的域名或 IP 地址。event.type
:事件类型,默认为message
。
SSE 优点
相比传统的轮询方法,SSE 有如下优点:
- 数据实时推送,延迟低。
- 服务器可通过数据 ID,标识每条数据,客户端可保证数据不丢失。
- 协议简单易用,兼容性较好。
SSE 库源码分析
SSE 主要代码
下面是一个简化版的 SSE 库实现,主要由以下三个部分组成:
----- --- - ---------------- ------- - --- - -------- - ---- ------------ - -------- ----------- - ----- ----------- - --- ------ - ---------------------- --------- - --------------------- ---------- - --------- - ----------- - --- --------------------- -------------- ------------------------------------ ------- -- - ----------------------- -- --------- ------- --- ------------------------------------- ------- -- - ----------------- ----- ----------- ------- --- --------------------------------------- ------- -- - -------------- ------- ----------- ------- ----- - ----- ----- ----------- - - ------ ----- -------- - ---------------------- -- ---------- - ---------- ----- ----------- --- - --- - ------- - -- ------------- - -------------------- -------------------- - - -
SSE 类主要由四个方法组成:
- 构造函数
constructor(url, options = {})
:创建 SSE 类实例,初始化 SSE 服务地址和选项。 addEventListener(name, callback)
:监听事件,当收到服务器端推送的该类型消息时,触发回调函数。connect()
:与 SSE 服务建立连接,创建EventSource
对象并注册事件监听。close()
:关闭 SSE 服务连接,清理监听事件。
构造函数中,传入 SSE 服务地址和选项。其中,选项包含如下属性:
headers
:HTTP 请求头信息。withCredentials
:是否携带跨域凭证。retryInterval
:尝试重新连接的时间间隔,单位为毫秒,默认为 3000ms。
在 connect()
方法中,首先创建 EventSource
对象,并添加 open
、error
和 message
三种事件的监听。其中,message
事件的监听是必须的,因为它是 SSE 推送数据的主要入口。当接收到新的 SSE 消息时,会触发该事件回调 event
。
在 message
事件回调函数中,首先获取响应数据中的类型 type
、数据 data
和上一次事件 ID lastEventId
,然后根据 type
查找注册的回调函数,并调用其回调函数处理数据。
在 close()
方法中,首先判断 EventSource
是否存在,然后关闭连接并清理事件监听。
SSE 库示例代码
下面展示了如何使用 SSE 库实现消息推送。
服务端代码
对于 SSE 服务,无需特别设置,只需要使用标准的 HTTP 服务器即可。下面是一个使用 Node.js + Express 实现的 SSE 服务端示例:
----- ------- - ------------------- ----- --- - ---------- ------------- ---- ----- -- - --------------- ------ ------------- ------------- --------------- -------------------- ---------------- ---------- --- ------------------- ----- ----- - -------------- -- - ---------------- ----- ---------------------------- -- ------ --------------- -- -- - --------------------- --- --- ----- ---- - ---------------- -- ----- ---------------- -- -- - ---------------- ------ -- --------- -- --------------------------- ---
服务端代码中,首先使用 express
创建一个 HTTP 服务器,然后设置响应头信息,保证浏览器能正常解析 SSE 响应。接着,每隔 1 秒钟向客户端推送一条当前时间的消息。
客户端代码
在客户端代码中,首先创建一个 SSE 对象并监听 message
事件。当收到服务端推送的数据时,将数据追加到页面上:
--------- ----- ----- ---------- ------ ----- ---------------- ---------- ------------ ------- ------ --- ------------------- -------- ----- ------ - ------------------------------------ ----- --- - --- --------------- ------------------------------- -- ---- -- -- - ----- -- - ----------------------------- -------------- - ----- ----------------------- --- -------------- --------- ------- -------
客户端代码主要有两个部分:HTML 页面和 JavaScript 代码。HTML 页面中定义了一个 ul
元素用于展示接收到的消息。JS 代码中,首先创建一个 SSE 对象,并监听 message
事件。当收到服务端推送的消息时,将消息添加到 messages
列表中。
总结
SSE 库是一种轻量级的浏览器与服务器之间的消息推送技术,它通过 HTTP 协议的长连接,实现了服务器端向客户端实时推送数据的能力。相比传统的轮询方法,SSE 延迟低、兼容性好、易用性高,是消息推送的良好解决方案。
来源:JavaScript中文网 ,转载请联系管理员! 本文地址:https://www.javascriptcn.com/post/665378f8d3423812e47e82af