从北京暴雨开始聊聊 Server-sent events
又到721,每年的这几天,都会变得尤为小心。清晰记得2012年的721是个周六,在公司加班,天就跟漏个窟窿一样不停的下,当时站在落地窗前,拍了这张照片。
回归正题,最近在做 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。
Demo 主要分为两块
- Server 端负责推送event stream
- Client 端负责监听,接收到数据后,判断是自定义事件还是默认时间,然后采取不同的行为。
执行npm install & node main.js
后,访问http://localhost:3000/
效果如下:
事件流是混淆了默认事件和自定义事件,随机发送的。
左侧信号灯区域,是自定义事件,接收来自于 Server 端发送的stop/go/warning
事件,并用信号灯的形式表示。
右侧是消息区域处理message
事件,如果发送事件流中没有 event
字段,则这些消息会被视为 message
事件,示例中把接收到消息内容打印到屏幕右侧。
事件格式流
详细基本原理介绍在 MDN 和 EventSource 已经写的比较详细。
EventSource
默认提供三个实例属性readyState/url/withCredentials
,三种事件的处理open/message/error
,一个close
方法。
event stream 的事件流格式会比较奇怪,在写 Demo 的时候,这一步卡住了,默认按照message
的方式是能跑通的,把所有的消息都通过 message 传递,然后再处理似乎不合适,还是要先区分 event,再传递消息。
后面仔细研究下事件流的格式才发现,是因为缺少换行符导致的,并且事件流限制解析字段。
注意数据流格式、注意数据流格式、注意数据流格式
技术方案对比:轮询、长轮询、长链接和全双工
直接看图吧
对比维度 | 短轮询 | 长轮询 Comet | 长链接 SSE | 全双工 Websocket |
---|---|---|---|---|
通讯 协议 | Http | Http | Http | WebSocket |
触发方式 | 轮询 | 轮询 | 事件 | 事件 |
优点 | 简单、易于理解、实现无难度 | 相比减少很多 http 请求次数 | 不需要客户端发送请求,不需要建立和保持大量的请求,节约资源,主动型 | 双向通信,性能开销小,安全性高,可扩展 |
缺点 | 不断建立 http 连接,浪费资源,服务端压力大,依赖于比较快的处理速度,被动型 | 连接挂起也浪费资源,要处理并发能力,被动型 | 连接数限制 | 服务端逻辑略复杂,需数据传输需解析 |
当然,每种方案都有它适用的场景,选择最适合的才是最佳的方案。
结束语
文中如有疏漏,欢迎留言讨论,共同学习成长,为了掘金。
转载自:https://juejin.cn/post/7259237176863752250