likes
comments
collection
share

从北京暴雨开始聊聊 Server-sent events

作者站长头像
站长
· 阅读数 19

又到721,每年的这几天,都会变得尤为小心。清晰记得2012年的721是个周六,在公司加班,天就跟漏个窟窿一样不停的下,当时站在落地窗前,拍了这张照片。

从北京暴雨开始聊聊 Server-sent events

回归正题,最近在做 AI 原生的应用项目,技术上前后端通信选择是的 websocket(技术选择源于有比较多的项目积累和实操经验),后被推荐使用 SSE,嗯?初次听到给我整的一愣一愣的,感觉这些年的前端白干了,咋不知道这是个 what? 如果通俗的讲,服务端主动给客户端发消息,咱们肯定就都明白了。

服务器推送事件

Server-sent events,简称SSE,HTML5 规范首次提出(Server-sent events),用于从服务端实时推送数据到浏览器端。可以构建实时性更高的Web应用程序,例如股票价格更新、天气预报、社交媒体通知等。发送事件的服务器端脚本需要使用 text/event-stream MIME 类型响应内容,每个通知以文本块形式发送,并以一对换行符结尾。

说到这儿,event stream发生过大名鼎鼎的比特币事件呐,当年的链接还在I don't know what to say,当年只顾吃瓜,咋就没好好研究一下,干!

上手体验

我们基于一个可运行的示例,以便于更好的学习和理解SSE。

server-sent-events-start

Demo 主要分为两块

  • Server 端负责推送event stream
  • Client 端负责监听,接收到数据后,判断是自定义事件还是默认时间,然后采取不同的行为。

执行npm install & node main.js后,访问http://localhost:3000/

效果如下: 从北京暴雨开始聊聊 Server-sent events

事件流是混淆了默认事件和自定义事件,随机发送的。

左侧信号灯区域,是自定义事件,接收来自于 Server 端发送的stop/go/warning事件,并用信号灯的形式表示。

右侧是消息区域处理message事件,如果发送事件流中没有 event 字段,则这些消息会被视为 message 事件,示例中把接收到消息内容打印到屏幕右侧。

从北京暴雨开始聊聊 Server-sent events

事件格式流

详细基本原理介绍在 MDNEventSource 已经写的比较详细。

EventSource默认提供三个实例属性readyState/url/withCredentials,三种事件的处理open/message/error,一个close方法。

event stream 的事件流格式会比较奇怪,在写 Demo 的时候,这一步卡住了,默认按照message的方式是能跑通的,把所有的消息都通过 message 传递,然后再处理似乎不合适,还是要先区分 event,再传递消息。

后面仔细研究下事件流的格式才发现,是因为缺少换行符导致的,并且事件流限制解析字段。

注意数据流格式、注意数据流格式、注意数据流格式

技术方案对比:轮询、长轮询、长链接和全双工

直接看图吧

从北京暴雨开始聊聊 Server-sent events

对比维度短轮询长轮询 Comet长链接 SSE全双工 Websocket
通讯 协议HttpHttpHttpWebSocket
触发方式轮询轮询事件事件
优点简单、易于理解、实现无难度相比减少很多 http 请求次数不需要客户端发送请求,不需要建立和保持大量的请求,节约资源,主动型双向通信,性能开销小,安全性高,可扩展
缺点不断建立 http 连接,浪费资源,服务端压力大,依赖于比较快的处理速度,被动型连接挂起也浪费资源,要处理并发能力,被动型连接数限制服务端逻辑略复杂,需数据传输需解析

当然,每种方案都有它适用的场景,选择最适合的才是最佳的方案。

结束语

文中如有疏漏,欢迎留言讨论,共同学习成长,为了掘金。