前言
Web 技术因其广泛应用和功能强大而备受关注。前端开发者不仅需要掌握基础的 HTML、CSS 和 JavaScript 技术,还需要深入了解服务器与客户端之间的通信协议。其中,SSE 技术可用于实时数据传输。然而,SSE 的消息类型限制较多,需要开发者合理选择。本文将介绍 SSE 的数据发送方式及消息类型,并提供避坑指南,帮助开发者尽快掌握 SSE 技术。
SSE 数据发送方式
SSE (Server-Sent Events) 是一种 Web 技术,用于实现服务器推送数据到客户端。SSE 最大的特点就是无需像 WebSocket 那样建立全双工连接,减少服务器负担。以下是 SSE 发送数据的方式。
服务端代码
-- -------------------- ---- ------- ----- ---- - ---------------- ----- -- - -------------- ----------------------- ---- -- - ------------------ - --------------- -------------------- ---------------- ----------- ------------- ------------ --- -------------- -- - ----- ------- - ------ ----- ---------------------------------- ------------------- -- ------ ----------------展开代码
服务端代码首先创建了一个 HTTP 服务器,并使用 res.writeHead()
方法设置了响应头信息。注意,使用 SSE 技术需要设置响应头的 Content-Type
为 text/event-stream
,并设置 Cache-Control
为 no-cache
。此外,还需要设置 Connection
为 keep-alive
,告诉浏览器保持长连接,等待服务器推送数据。
服务端代码中,使用 setInterval()
定时发送数据。SSE 技术使用的是 HTTP 协议的长连接机制,通过发送多条数据和 event
字段来完成数据的传输。每条数据需要以 data:
开头,以 \n\n
结尾,其中 \n\n
表示一条数据的结束。event
字段用于指定数据的类型,可以在客户端中通过 event
字段进行事件的筛选。
客户端代码
-- -------------------- ---- ------- --------- ----- ------ ------ ----- ---------------- ---------- --------------- ------- ------ ---- --------------- -------- ----- ----------- - --- -------------------------------------- ----- --- - ------------------------------- ---------------------------------------- ------- -- - ----- ---- - ----------------------- ------------- -- --------- - ------- -- ------- --------- ------- -------展开代码
客户端代码中,使用 new EventSource()
方法创建 SSE 对象。构造函数中需要传入服务器端的 URL。客户端代码中,我们还创建了一个 <div>
元素,用来显示服务端发送过来的数据。此外,我们在客户端代码中可以通过 addEventListener()
方法监听服务端发送过来的 my-event
事件,并将数据展示在页面上。
SSE 的消息类型选择
在使用 SSE 时,开发者需要注意服务端发送消息的类型。SSE 的消息类型分为三种:普通消息、注释和事件。以下是三种消息类型的具体内容。
普通消息
服务端代码
const message = `data: ${new Date().toLocaleTimeString()}\n\n`; res.write(message);
客户端代码
eventSource.onmessage = (event) => { const data = event.data; };
普通消息是最常见的一种消息类型,用于传输普通的文本、数字等类型的数据。服务端发送普通消息时,需要在数据前面添加 data:
,在数据末尾添加 \n\n
。在客户端中,可以通过 onmessage
方法获取服务端发送过来的数据。
注释
服务端代码
const message = `:${new Date().toLocaleTimeString()}\n\n`; res.write(message);
客户端代码
eventSource.onmessage = (event) => { const comment = event.data.startsWith(":"); };
注释消息类型是 SSE 的一大特色。注释消息不会作为文本数据显示在客户端上,而是起到了一种服务端发送消息的提示作用。服务端发送注释时,需要在数据前面添加 :
,在数据末尾添加 \n\n
。在客户端中,可以通过判断数据是否以 :
开头来判断服务端发送的是否是注释消息。
事件
服务端代码
const message = `event: my-event\ndata: ${JSON.stringify(data)}\n\n`; res.write(message);
客户端代码
eventSource.addEventListener("my-event", (event) => { const data = JSON.parse(event.data); });
事件消息类型是 SSE 的另一个特色。通过事件类型,客户端可以根据不同的事件类型进行不同的操作。在服务端发送事件消息时,需要在数据前面添加 event: my-event
,my-event
即为自定义的事件类型,可以根据实际需求自行修改。在客户端中,可以通过 addEventListener()
方法监听服务端发送的 my-event
事件,并获取相应的数据。
避坑指南
在使用 SSE 时,开发者可能会遇到以下几个问题。
问题一:记得使用 while 循环
服务端发送 SSE 数据时,需要加上 \n\n
来结束一条消息的传输。因此,可能会出现一些消息还没有发送完成,下一条消息就被发送出去了。这会导致客户端无法接收到完整的消息。为了避免这种情况的发生,需要在服务端代码中使用 while
循环,确保完整的数据被发送。
服务端代码示例:
-- -------------------- ---- ------- -------------- -- - ----- ------- - ------ ----- ---------------------------------- ------------------- ----- --------------- - ---- - ----------- - ------------------- -------------- - ----------- - -- ------展开代码
问题二:不要忘记发送周期性的注释消息
发送周期性的注释消息可确保服务端与客户端的连接保持活跃。如果在一定时间内没有发送任何消息,连接可能会断开。为了避免这种情况的发生,建议在服务端代码中周期性地发送注释消息。
服务端代码示例:
setInterval(() => { res.write(":\n\n"); }, 10000);
问题三:处理消息类型的兼容性
不同浏览器对 SSE 的消息类型支持程度不同。有些浏览器只支持普通消息类型,有些浏览器不能处理事件消息类型。为了提高兼容性,建议在服务端发送消息时,同时发送注释和事件消息,这样即使某些浏览器不支持某种消息类型,也不会造成影响。
服务端代码示例:
setInterval(() => { res.write(`data: ${new Date().toLocaleTimeString()}\n\n`); res.write(":\n\n"); res.write(`event: my-event\ndata: ${JSON.stringify(data)}\n\n`); }, 1000);
结语
本文介绍了 SSE 的数据发送方式及消息类型选择,并提供了避坑指南。希望开发者通过本文的介绍,可以尽快掌握 SSE 技术,减少开发过程中的困难。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67930864504e4ea9bd711897