当前位置:网站首页>「Web应用架构」轮询,SSE 和WebSocket,如何选择合适的?
「Web应用架构」轮询,SSE 和WebSocket,如何选择合适的?
2022-08-10 17:30:00 【51CTO】
构建实时Web应用程序有点挑战,我们需要考虑如何将数据从服务器发送到客户端。能够“主动”实现这一功能的技术已经存在了很长时间,并且仅限于两种通用方法:客户端请求或服务器请求。
实现这些的几种方法:
- 长/短轮询(客户端拉动)
- WebSockets(服务器推送)
- 服务器发送的事件(服务器推送)
- 客户端拉取-客户端以一定的定期间隔向服务器请求更新
- 服务器推送-服务器正在主动将更新推送到客户端(客户端拉取的反向操作)
让我们以一个简单的用例来比较以上技术,然后选择合适的技术。
范例:
我们的示例用例非常简单。我们需要开发一个仪表板Web应用程序,该应用程序可以流转来自(GitHub / Twitter / .. etc)等网站的活动列表。这个应用程序的目的是从上面列出的各种方法中选择合适的一种。
1.使用轮询:
轮询是一种技术,客户端通过该技术定期向服务器请求新数据。我们可以通过两种方式进行轮询:短轮询和长轮询。简单来说,短轮询是基于AJAX的计时器,它以固定的延迟进行调用,而长轮询则基于Comet(即,当服务器事件发生时,服务器将无延迟地将数据发送到客户端)。两者都有优点和缺点,并根据用例进行调整。有关深入的详细信息,请阅读StackOverflow社区给出的答案。
让我们看看一个简单的客户端长轮询代码段的外观:
这基本上是一个长轮询功能,它像往常一样第一次运行,但是它设置了三十(30)秒的超时,并且在每次对服务器进行Async Ajax调用之后,回调都会再次调用Ajax。
AJAX调用可在HTTP协议上运行,这意味着默认情况下,对同一域的请求应进行多路复用。我们发现这种方法存在一些陷阱。
多路复用(轮询响应实际上无法同步)
轮询需要3次往返(TCP SIN,SSL和数据)
超时(如果连接保持空闲时间太长,代理服务器将关闭连接)
您可以在这里阅读更多关于现实世界的挑战。
2.使用WebSockets:
WebSocket只是客户端和服务器之间的持久连接。这是一种通过单个TCP连接提供全双工通信通道的通信协议。
RFC 6455声明WebSocket“旨在在HTTP端口80和443上工作,并支持HTTP代理和中介”,从而使其与HTTP协议兼容。为了实现兼容性,WebSocket握手使用HTTP升级标头将HTTP协议更改为WebSocket协议。HTTP和WebSocket都位于OSI模型的应用程序层,因此依赖于第4层的TCP。
有一个MDN文档详细解释了WebSocket,我也建议您阅读它。
让我们看看一个非常简单的WebSocket客户端实现的样子:
如果服务器支持WebSocket协议,它将同意升级,并将通过响应中的Upgrade标头传达此信息。
让我们看看如何在Node.JS(服务器)中实现:
一旦我们从GitHub事件API获得数据,就可以在建立连接后将其流式传输到客户端。对于我们的场景,这种方法也有一些陷阱。
- 使用WebSockets,我们需要自己处理许多由HTTP处理的问题。
- WebSocket是用于传输数据的另一种协议,它不会通过HTTP / 2连接自动多路复用。在服务器和客户端上实现自定义多路复用有点复杂。
- WebSocket是基于帧的,而不是基于流的。当我们打开网络标签。您可以看到WebSocket消息在frame中列出。
有关WebSocket的详细信息,请查看这篇很棒的文章,在这里您可以阅读有关碎片以及如何在后台进行处理的更多信息。
3.使用SSE:
SSE是一种机制,一旦建立了客户端-服务器连接,服务器就可以将数据异步推送到客户端。然后,只要有新的“大块”数据可用,服务器就可以决定发送数据。可以将其视为单向发布-订阅模型。
它还提供了一个标准的JavaScript客户端API,称为EventSource,已在大多数现代浏览器中实现,作为W3C的HTML5标准的一部分。 Polyfills可用于不支持EventSource API的浏览器。
我们可以看到Edge和Opera Mini落后于此实现,对于SSE而言,最重要的案例是针对移动浏览器设备,因为这些浏览器没有可行的市场份额。Yaffle是事件源的众所周知的pollyfill。
由于SSE是基于HTTP的,因此它很自然地与HTTP / 2相适应,并且可以结合使用以实现两者的最佳选择:HTTP / 2处理基于多路复用流的有效传输层,而SSE为应用程序提供API以实现 推。因此,开箱即用地通过HTTP / 2实现多路复用。连接断开时会通知客户端和服务器。通过使用消息维护唯一的ID,服务器可以看到客户端错过了n条消息,并在重新连接时发送了未完成消息的积压。
让我们看看示例客户端实现的外观:
此代码段非常简单。它连接到我们的源并等待接收消息。现在,示例NodeJS服务器将如下所示。
我们从这种方法中获得的主要好处是:
- 实施更简单,数据效率更高
- 开箱即用地通过HTTP / 2自动多路复用
- 将客户端上数据的连接数限制为一个
如何在SSE,WebSocket和Polling中进行选择?
经过漫长而详尽的客户端和服务器实施之后,SSE似乎是我们解决数据交付问题的最终答案。也有一些问题,但是可以解决。
可以利用服务器发送事件的应用程序的一些简单示例:
- 实时股价流图
- 重要事件的实时新闻报道(发布链接,推文和图片)
- 由Twitter的流API提供的实时Github / Twitter仪表板墙
- 监视服务器统计信息(如正常运行时间,运行状况和正在运行的进程)的监视器。
但是,SSE不仅是其他提供快速更新的方法的可行替代方案。在某些特定情况下,例如在SSE被证明是理想解决方案的情况下,每个人都可以胜过其他人。考虑一个像MMO(大型多人在线)游戏这样的场景,该场景需要来自连接两端的大量消息。在这种情况下,WebSockets将压制SSE。
如果您的用例需要显示实时的市场新闻,市场数据,聊天应用程序等,例如在我们的案例中,依靠HTTP / 2 + SSE将为您提供有效的双向通信渠道,同时又能获得留在其中的好处HTTP世界。
如果您想为我们的用例获取示例客户端-服务器实现,请签出GitHub代码。
资源
- “caniuse.com”
- “使用服务器发送的事件进行流更新”,HTML5 Rocks的Eric Bidelman
- “使用HTML5 SSE的数据推送应用”,O’Reilly Media的Darren Cook
感谢您阅读
QQ群【11107777】
边栏推荐
- 事务的隔离级别,MySQL的默认隔离级别
- DASCTF2022.07 empowerment competition WEB topic recurrence
- R语言创建列表数据(list):根据名称索引列表元素、双方括号访问单个元素、单方括号访问子列表
- 【接入指南 之 直接接入】手把手教你快速上手接入HONOR Connect平台(中)
- TradingView_学习笔记
- 全新接口——邻家好货 API
- R语言使用ggpubr包的ggbarplot函数可视化柱状图、设置add参数为mean_se和jitter可视化不同水平均值的柱状图并为柱状图添加误差线(se标准误差)和抖动数据点分布
- 8.9模拟赛总结
- R语言拟合ARIMA模型:使用forecast包中的auto.arima函数自动搜索最佳参数组合、模型阶数(p,d,q)、如果已知阶数则直接使用arima函数构建模型(order参数指定阶数)
- BalsnCTF2021
猜你喜欢
随机推荐
8.9模拟赛总结
DASCTF2022.07 empowerment competition WEB topic recurrence
6月各手机银行活跃用户较快增长,创半年新高
redis分布式锁
多线程与高并发(11)——经典面试题之实现一个容器,提供两个方法,add,size。
Moonbeam于Moonbase Alpha构建新式XCM对EVM跨链功能
Selenium - 如何操作下拉框、弹出框、滚动条?
百度、四维图新、高德争“鲜”恐后
The DGIOT platform displays the whole process code analysis of OPC reporting data in real time
神经网络的图像识别技术,神经网络识别图像原理
中国芯片的营收首破万亿,优势凸显的成熟工艺产能将称霸全球
基于AWS构建云上数仓第二步:AWS常见服务简介
unr #6day1 T2题解
document.title获取当前网页的标题
pip安装时 fatal error C1083 无法打开包括文件 “io.h” No such file or directory
defi质押借贷理财挖矿dapp系统开发逻辑
Your local docbook2man was found to work with SGML rather than XML
Talk about cloud native data platform
本周四晚19:00知识赋能第六期第5课丨OpenHarmony WiFi子系统
HTTP学习——协议与术语、HTTP、缓存、Cookie