双向通信是现代 Web 应用必不可少的一部分。在传统的 Web 应用中,客户端向服务器发送请求,服务器处理请求并返回响应。但随着 Web 应用变得更加复杂,我们需要一种实现服务器主动向客户端推送数据的技术,以提供实时反馈和动态内容更新的功能。
Server-sent Events(SSE)是一种使用 HTTP 协议向客户端推送实时事件的技术。它允许服务器向客户端发送 DOM 事件,这些事件的内容可以是任何格式,比如文本、JSON 或 XML。相比于 Websocket 和长轮询(long-polling),SSE 更加轻量级和简单易用,不需要额外的协议和服务器端库。
本文将介绍如何轻松实现 Server-sent Events 推送,并展示一个示例代码,供读者参考。
1、SSE 基础概念
在正式介绍如何实现 SSE 推送之前,我们先来了解一些 SSE 的基础概念。
1.1 事件流(EventStream)
SSE 是基于事件流(EventStream)的技术。事件流是由一个或多个事件构成的数据流,服务器通过 HTTP 协议将事件流发送给客户端。一个事件流可以包含任意数量的事件,每个事件由一组字段构成,通常包括事件的名称和数据。
1.2 事件(Event)
事件是服务器向客户端推送的核心内容。每个事件由一个事件标识符(event ID)、事件类型(event type)和数据(data)组成。其中,事件标识符和事件类型都是可选的,数据必须存在。事件类型可以自定义,用于客户端识别不同类型的事件。如果事件标识符存在,则客户端会保存最新的事件标识符,以便在重新连接时从上次中断的事件处继续接收。
1.3 MIME 类型(MIME Type)
SSE 使用特定的 MIME 类型(text/event-stream)来标识数据流。在 HTTP 头部中,使用 Content-Type 属性指定 MIME 类型,例如:
Content-Type: text/event-stream
2、实现 SSE 推送
有了上述基础概念,我们可以开始介绍如何实现 SSE 推送了。
2.1 HTTP 响应头
在服务器端,我们需要设置 HTTP 响应头,以告知客户端发送的是一段 SSE 数据流。具体来说,我们需要设置以下几个属性:
- Content-Type:指定 MIME 类型,例如
text/event-stream
; - Cache-Control:指定缓存控制,通常设置为
no-cache
; - Connection:指定持续连接,通常设置为
keep-alive
; - Access-Control-Allow-Origin:指定跨域资源共享(CORS),通常设置为
*
。
以下是一个示例的 HTTP 响应头:
-------- --- -- ------------- ----------------- -------------- -------- ----------- ---------- ---------------------------- -
2.2 事件流格式
接下来,我们需要设置 SSE 数据流的格式。一个 SSE 数据流包含多个事件,每个事件需要按特定格式进行组合。一个完整的事件格式如下:
------ ------ ----- --- ------ --- ----- ------ -----
其中,{event type}
表示事件类型,可以任意定义,但通常采用小写字母和连字符的形式,例如 update-event
。{event id}
表示事件标识符,可以省略,如果存在,则需要是唯一的。{event data}
表示事件数据,可以是任意格式的数据,例如文本、JSON 或 XML。
注意,每个事件需要以一个空行结尾。
2.3 服务器端推送数据
有了上述基础概念,我们可以开始实现 SSE 推送了。以下是一个 Node.js Express 服务器端的示例代码:
----- --- - --------------------- ----- ---- - ---------------------------- -- --- ----- ------------------ ----- ---- -- - -- --- --- -------- ------- ------------------ - --------------- -------------------- ---------------- ----------- ------------- ------------- ------------------------------ --- --- -- ---- --- ---- ---------------- ------ ------------- ---------------- --- --- ----------- ----------------- ----------------- ---------------- - ---------- ----- -- - ------ ------- -------- -- ----- --- ---------- ----- -- ------- ------------- -- - ---------- -- ------- --- ----------------- -- -- - ------------------- -- --------- -- ---- ------- ---
在上述代码中,我们创建了一个名为 /stream
的 SSE 路由,设置了 HTTP 响应头,然后发送了几个事件(包括文本和 JSON 数据)。最后,我们通过 setTimeout()
函数在 20 秒之后关闭了连接。需要注意的是,在 SSE 中,服务器不会自动关闭连接,需要手动结束。
2.4 客户端接收数据
客户端可以通过 JavaScript 的 EventSource
对象来接收 SSE 数据。EventSource
对象会自动处理连接、断开和重新连接等事件,能够轻松实现 SSE 接收功能。以下是一个基本的 SSE 客户端示例代码:
----- ------ - --- ----------------------- ---------------------------------- ------- -- - --------------------- ---------- ------------ --- --------------------------------------- ------- -- - --------------------- ------ -------- ------------------------ --- -------------------------------- ------- -- - ----------------------- ------- ---
在上述代码中,我们创建了一个 EventSource
对象,并指定 SSE 数据流的 URL。然后,我们通过 addEventListener()
函数来监听事件。在本例中,我们监听了 message
事件和自定义事件 custom-event
。当接收到事件时,我们可以通过 event.data
属性来获取事件的数据。
3、总结
本文介绍了 Server-sent Events(SSE)推送的基础概念和实现方式,并提供了一个 Node.js Express 服务器端和基本的客户端示例代码。通过本文的学习,读者可以轻松实现 SSE 推送功能,并扩展自己的 Web 应用程序。
来源:JavaScript中文网 ,转载请联系管理员! 本文地址:https://www.javascriptcn.com/post/64f3f2cdf6b2d6eab3d28850