提问人:Inaimathi 提问时间:2/22/2012 最后编辑:Brian Tompsett - 汤莱恩Inaimathi 更新时间:7/8/2021 访问量:34009
服务器发送的事件与轮询
Server-Sent Events vs Polling
问:
HTML5 SSE 和直接 Ajax 轮询之间有很大的区别(在性能、浏览器实现可用性、服务器负载等方面)吗?从服务器端来看,似乎每~3秒左右就会点击指定的页面(尽管我知道时间是灵活的)。EventSource
诚然,在客户端设置比设置计时器并经常使用更简单,但还有其他方法吗?它是否发送了更少的标题,或者我缺少一些其他魔法?$.get
答:
Ajax 轮询增加了大量的 HTTP 开销,因为它不断建立和拆除 HTTP 连接。正如 HTML5 Rocks 所说,“另一方面,服务器发送的事件从头开始设计,效率很高。
服务器发送的事件打开单个长期存在的 HTTP 连接。然后,服务器在拥有数据时单向发送数据,客户端无需请求数据或执行任何操作,只需等待消息。
服务器发送事件的一个缺点是,由于它们会创建与服务器的持久连接,因此您可能会与服务器建立许多打开的连接。某些服务器比其他服务器更好地处理大量并发连接。也就是说,您在轮询时会遇到类似的问题,以及不断重新建立这些连接的开销。
大多数浏览器都很好地支持服务器发送的事件,当然,值得注意的例外是 IE。但是有几个polyfills(和一个jQuery插件)可以解决这个问题。
如果你正在做一些只需要单向通信的事情,我肯定会选择服务器发送的事件。正如你所提到的,服务器发送的事件往往更简单、更干净,可以在客户端实现。您只需要为消息和事件设置侦听器,浏览器会处理低级的事情,例如断开连接时重新连接等。在服务器端,它也相当容易实现,因为它只使用简单的文本。如果您发送 JSON 编码的对象,您可以通过 JSON.parse()
轻松地在客户端上将它们转换为 JavaScript 对象。
如果你在服务器上使用PHP,你可以使用json_encode()
将字符串、数字、数组和对象转换为正确编码的JSON。其他后端语言也可能提供类似的功能。
评论
max_children
我只想在所说的内容上添加一个更高的视角,那就是 SSE 是发布-订阅模型,而不是 AJAX 情况下的恒定轮询。
通常,这两种方法(轮询和发布-订阅)都试图解决如何在客户端上保持最新状态的问题。
1) 轮询模型
这很简单。客户端(浏览器)首先获取初始状态(页面),为了进行更新,它需要定期请求状态(页面或其部分)并将结果处理为当前状态(刷新整个页面或在AJAX的情况下将其智能呈现为其部分)。
当然,一个缺点是,如果服务器状态没有发生任何事情,资源(CPU、网络等)就会被不必要地使用。另一个是,即使状态发生变化,客户端也只会在下一个轮询期间获得它,而不是尽快获得它。人们经常需要评估这两件事之间的良好时间折衷方案。
轮询的另一个示例是线程中的旋转等待。
2)发布-订阅模式
其工作原理如下:
- (客户端首先请求并显示一些初始状态)
- 客户端订阅服务器(发送一个请求,可能带有一些上下文,如事件源)
- 服务器将对客户端的引用标记为其某些客户端引用存储库
- 如果状态更新,服务器会根据对它所持有的客户端的引用向客户端发送通知;即它不是对请求的响应,而是由服务器发起的消息
- 好的客户在对通知不再感兴趣时会取消订阅
这是 SSE,或者在线程中处理一个可等待的事件,作为另一个例子。 如前所述,一个自然的缺点是服务器必须知道其所有订阅的客户端,根据实现的不同,这可能是一个问题。
评论