服务器发送的事件与轮询
在HTML5 SSE和直接Ajax轮询之间,性能,浏览器实现可用性,服务器负载等方面有很大的不同吗? 从服务器端来看,似乎一个EventSource
只是每隔3秒钟左右敲击指定的页面(尽pipe我明白时间是灵活的)。
当然,在客户端设置比设置一个定时器更简单,并且每$.get
就要$.get
,但是还有其他的东西吗? 它是否发送更less的标题,或者做一些其他的魔法我失踪?
由于Ajax轮询不断build立和拆除HTTP连接,因此Ajax轮询会增加很多HTTP开销。 正如HTML5 Rocks所说的那样, “服务器发送的事件,另一方面,从头开始被devise为高效”。
服务器发送的事件打开一个长期生存的HTTP连接。 然后,服务器在发送数据时单向发送数据,客户端不需要请求它,也不需要等待消息。
服务器发送事件的一个缺点是,因为他们创build了一个到服务器的持久连接,所以你可能有很多打开的连接到你的服务器。 一些服务器比其他服务器更好地处理大量的并发连接 。 也就是说,你会有类似的投票问题加上不断重build这些连接的开销。
服务器发送的事件在大多数浏览器中都得到很好的支持 ,当然这个例外是IE。 但是有几个 polyfill (和一个jQuery插件 )可以解决这个问题。
如果你正在做的事情只需要单向沟通,我肯定会去与服务器发送的事件。 正如你所提到的,服务器发送的事件在客户端更容易实现。 您只需要为消息和事件设置侦听器,而浏览器会处理低级别的事情,如断开连接时重新连接等等。在服务器端,由于它只使用简单的文本,因此也很容易实现。 如果您发送JSON编码对象,则可以通过JSON.parse()
将它们轻松地转换为客户端上的JavaScript对象。
如果您在服务器上使用PHP,则可以使用json_encode()
将string,数字,数组和对象转换为正确编码的JSON。 其他后端语言也可能提供类似的function。
我只会增加更高层次的观点,那就是SSE是发布 – 订阅模式,而不是在AJAX的情况下进行持续轮询。
一般来说,轮询和发布订阅都试图解决如何在客户端保持最新状态的问题。
1)轮询模式
很简单。 客户端(浏览器)首先得到一个初始状态(页面),并且为了更新它,它需要周期性地请求状态(页面或其部分)并将结果处理成当前状态(刷新整个页面或者将其显式地转换成部分在AJAX的情况下)。
自然,一个缺点是,如果服务器状态没有发生,资源(CPU,networking等)被不必要地使用。 另一个是,即使状态改变,客户只能在下一个投票期间得到它,而不是尽快。 人们经常需要评估这两件事情之间的妥协。
投票的另一个例子是线程中的自动等待。
2)发布 – 订阅模式
它的工作原理如下:
- (客户端首先请求并显示一些初始状态)
- 客户端订阅服务器(发送一个请求,可能与事件源一样的上下文)
- 服务器将对客户端的引用标记为某个客户端引用存储库
- 在状态更新的情况下,服务器根据对其持有的客户端的引用向客户端发送通知; 即它不是对请求的响应,而是服务器发起的消息
- 当好的客户不再对通知感兴趣时,退订
作为另一个例子,这是SSE,或者是在一个等待事件的线程中。 如上所述,一个自然的缺点是服务器必须知道所有的订购客户端,根据实现,这可能是一个问题。