服务器发送的事件与轮询

在性能、浏览器实现可用性、服务器负载等方面,HTML5SSE和直接的 Ajax 轮询有很大的区别吗?从服务器端来看,似乎 EventSource只是每3秒左右点击一次指定的页面(尽管我知道时间是灵活的)。

当然,在客户端设置比设置定时器和定时器 $.get更简单,但是还有什么别的吗?它会发送更少的头信息,还是会做一些我错过的其他魔法?

30674 次浏览

Ajax 轮询增加了许多 HTTP 开销,因为它不断地建立和拆除 HTTP 连接。就像 HTML5 Rocks HTML5岩石说的 “另一方面,服务器发送事件从头到尾都被设计得高效。”

服务器发送的事件打开一个长期存在的 HTTP 连接。然后,服务器在拥有数据时会单向发送数据,客户机不需要请求数据或做任何事情,只需等待消息。

服务器发送事件的一个缺点是,由于它们创建了到服务器的持久连接,因此您可能有许多到服务器的打开连接。一些服务器比其他服务器 更好地处理大量并发连接。也就是说,您在轮询时会遇到类似的问题,并且需要不断重新建立这些连接。

服务器发送的事件非常好的 支持大多数浏览器,当然 IE 是一个明显的例外。但是有一个 一对填充物(和一个 JQuery 插件)可以解决这个问题。

如果您所做的事情只需要单向通信,那么我肯定会选择服务器发送的事件。正如您所提到的,在客户端实现服务器发送的事件往往更简单、更干净。你只需要为消息和事件设置监听器,浏览器会处理一些底层的事情,比如断开连接后重新连接,等等。在服务器端,它也很容易实现,因为它只使用简单的文本。如果您发送 JSON 编码的对象,您可以通过 JSON.parse()轻松地将它们转换为客户机上的 JavaScript 对象。

如果您在服务器上使用 PHP,您可以使用 json_encode()将字符串、数字、数组和对象转换为正确编码的 JSON。其他后端语言也可能提供类似的功能。

我只想从一个更高的角度来看待刚才所说的,那就是 SSE 是发布-订阅模型,而不是在 AJAX 情况下的常量轮询。

通常,两种方式(轮询和发布-订阅)都试图解决如何在客户机上维护最新状态的问题。

1)投票模式

很简单。客户端(浏览器)首先获得一个初始状态(页面) ,为了让它更新,它需要定期请求状态(页面或其部分) ,并将结果处理为当前状态(在 AJAX 情况下刷新整个页面或智能地将其渲染为其部分)。

当然,一个缺点是,如果服务器状态没有发生任何事情,那么资源(CPU、网络、 ...)就会被不必要地使用。另一个原因是,即使状态发生变化,客户端也只能在下一轮投票期间获得,而不是尽快获得。人们经常需要评估两者之间的妥协。

轮询的另一个例子是线程处理中的 spinwait。

2)发布-订阅模式

它的工作原理如下:

  • (客户端首先请求并显示一些初始状态)
  • 客户端订阅服务器(发送一个请求,可能带有类似事件源的上下文)
  • Server 将对客户端的引用标记为对其某个客户端引用存储库的引用
  • 在状态更新的情况下,服务器根据对其持有的客户端的引用向客户端发送通知; 也就是说,它不是对请求的响应,而是由服务器发起的消息
  • 好的客户在对通知不再感兴趣时会取消订阅

这是 SSE,或者在线程一个可等待事件中,作为另一个示例。 如前所述,一个自然的缺点是服务器必须了解其所有订阅的客户端,这取决于实现,可能是一个问题。