概述
在 Web 应用中,很多时候需要实时推送服务端数据给客户端,例如即时聊天、股票行情、即时推送新闻等。在过去,开发者通常使用轮询(polling)方式定时请求服务端数据,然后将最新的数据得到并和之前获取的数据作对比,如果数据有变化,再更新到页面上。然而,轮询的常量请求会占用资源,造成页面的延迟和缓慢,而且如果服务端的数据推送比较频繁,轮询的效率也不高。
为了解决这些问题,HTML5 提供了一种新的技术:Server-sent Events,也就是服务端推送事件。Server-sent Events 区别于传统的 Ajax 请求,他是全双工通信协议,该协议只需要客户端通过 HTTP 连接一次,即可实现服务端推送数据到客户端,从而减少了不必要的 HTTP 连接,能够有效降低网络带宽开销。
实现 SSE 的服务端
实现 SSE 的服务端,需要遵循一些特殊的规则。具体而言,服务端需要向客户端发送一些固定的 HTTP 响应头,例如 Content-Type、Cache-Control,以注明该响应是一个 SSE 流。服务端每次发送数据必须以两个换行符结尾,这样客户端才能识别是否符合有效的 SSE 消息格式。
下面的代码演示了一个基本的 SSE 服务端实现:
-- -------------------- ---- ------- ----- ---- - ---------------- ------------------------------- ---- - ------------------ - --------------- -------------------- ---------------- ----------- ------------- ------------ --- ---------------------- - ----- --- - ------ ----- ---------------------------------- --------------- -- ------ ----------------
上面代码通过 Node.js 的 http 模块创建了一个 Web 服务器,响应头 Content-Type 设为 text/event-stream,Cache-Control 设为 no-cache,Connection 设为 keep-alive,以告诉客户端这是一个 SSE 流。然后我们设置一个定时器,每秒发送一个 SSE 消息到客户端,消息格式必须以 "data: " 开头,以两个换行符结尾。
实现 SSE 的客户端
实现 SSE 的客户端只需要在 JavaScript 中创建一个 EventSource 对象。EventSource 对象内置了几个公共事件回调,例如 onmessage 表示监听的消息事件,onopen 表示连接成功事件,onerror 表示错误事件。当服务端向客户端推送数据时,onmessage 事件回调函数会被触发,我们可以在该函数更新网页内容。
下面的代码演示了一个基本的 SSE 客户端实现:
-- -------------------- ---- ------- ----- ------ - --- ------------------------------------- ------------- - ---------- - --------------------- - -------------- - ---------- - ----------------------- - ---------------- - --------------- - ------------------------ -
上面代码中通过 new EventSource() 创建了一个 SSE 客户端,参数为服务端的地址和端口。然后我们监听了一些事件回调函数,比如 onopen、onerror、onmessage 等。当 SSE 消息到达客户端时会自动调用 onmessage 事件回调函数,并执行我们设定的逻辑。
延伸讨论
在实际项目中,SSE 现在已经广泛应用于消息推送、实时监控、在线问答等场景。然而,SSE 存在一些缺陷,例如浏览器兼容性问题、数据传输格式限制、无法双向通信等。因此,在实现时我们需要仔细考虑各种限制和缺点,以确保服务质量和用户体验。
总结
本文介绍了 Server-sent Events(SSE)技术的定义、实现和应用。我们重点介绍了 SSE 的服务端和客户端实现方法,并讨论了 SSE 的一些延伸问题和应用场景。相信读者在阅读本文后,能够更加深入和全面地了解 SSE 技术的特点和应用。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6517f29795b1f8cacd0176d4