Html 服务器发送的事件与轮询

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9397528/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 22:42:15  来源:igfitidea点击:

Server-Sent Events vs Polling

htmljavascript-eventsserver-sideserver-sent-eventsajax-polling

提问by Inaimathi

Is there a big difference (in terms of performance, browser implementation availability, server load etc) between HTML5 SSEsand straight up Ajax polling? From the server side, it seems like an EventSourceis just hitting the specified page every ~3 seconds or so (though I understand the timing is flexible).

HTML5 SSE和直接的 Ajax 轮询之间是否存在很大差异(在性能、浏览器实现可用性、服务器负载等方面)?从服务器端来看,似乎EventSource每隔 3 秒左右就会点击指定页面(尽管我知道时间是灵活的)。

Granted, it's simpler to set up on the client side than setting up a timer and having it $.getevery so often, but is there anything else? Does it send fewer headers, or do some other magic I'm missing?

诚然,在客户端设置比设置一个计时器并$.get经常使用它更简单,但还有什么别的办法吗?它会发送更少的标头,还是做一些我遗漏的其他魔法?

回答by Useless Code

Ajax polling adds a lot of HTTP overhead since it is constantly establishing and tearing down HTTP connections. As HTML5 Rocksputs it "Server-Sent Events on the other hand, have been designed from the ground up to be efficient."

Ajax 轮询会增加大量 HTTP 开销,因为它不断地建立和断开 HTTP 连接。正如HTML5 Rocks所说,“另一方面,服务器发送的事件是从头开始设计的,旨在提高效率。”

Server-sent events open a single long-lived HTTP connection. The server then unidirectionally sends data when it has it, there is no need for the client to request it or do anything but wait for messages.

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

One downside to Server-sent events is that since they create a persistent connection to the server you could potentially have many open connections to your server. Some servers handle massive numbers of concurrent connections betterthan others. That said, you would have similar problems with polling plus the overhead of constantly reestablishing those connections.

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

Server-sent events are quite well supported in most browsers, the notable exception of course being IE. But there are a coupleof polyfills(and a jQuery plugin) that will fix that.

大多数浏览器都很好地支持服务器发送的事件,当然 IE 是显着的例外。但也有一对夫妇polyfills(和jQuery插件),将解决这个问题。

If you are doing something that only needs one-way communication, I would definitely go with Server-sent events. As you mentioned Server-sent events tend to be simpler and cleaner to implement on the client-side. You just need to set up listeners for messages and events and the browser takes care of low-level stuff like reconnecting if disconnected, etc. On the server-side it is also fairly easy to implement since it just uses simple text. If you send JSON encoded objects you can easily turn them into JavaScript objects on the client via JSON.parse().

如果您正在做只需要单向通信的事情,我肯定会选择服务器发送的事件。正如您所提到的,服务器发送的事件在客户端实现起来往往更简单、更清晰。你只需要为消息和事件设置监听器,浏览器会处理低级的事情,比如断开连接时重新连接等。在服务器端,它也很容易实现,因为它只使用简单的文本。如果您发送 JSON 编码的对象,您可以通过JSON.parse().

If you are using PHP on the server you can use json_encode()to turn strings, numbers, arrays and objects into properly encoded JSON. Other back-end languages may also provide similar functions.

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

回答by Richard

I would only add a higher perspective to what's been said, and that is that SSE is publish-subscribe model as opposed to constant polling in case of AJAX.

我只会对所说的内容添加一个更高的观点,那就是 SSE 是发布订阅模型,而不是在 AJAX 的情况下进行持续轮询。

Generally, both ways (polling and publish-subscribe) are trying to solve the problem how to maintain an up-to-date state on the client.

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

1) Polling model

1) 轮询模型

It is simple. The client (browser) first gets an initial state (page) and for it to update, it needs to periodically request the state (page or its part) and process the result into the current state (refresh whole page or render it inteligently into its part in case of AJAX).

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

Naturally, one drawback is that if nothing happens with the server state the resources (CPU, network, ...) are used unnecessarily. Another one is that even if the state changes the clients gets it only at the next poll period, not ASAP. One often needs to evaluate a good period time compromise between the two things.

当然,一个缺点是如果服务器状态没有任何反应,资源(CPU、网络等)就会被不必要地使用。另一个是,即使状态发生变化,客户端也只能在下一个轮询期间获得它,而不是尽快。人们通常需要评估两件事之间的良好时期。

Another example of polling is a spinwait in threading.

轮询的另一个例子是线程中的自旋等待。

2) Publish-subscribe model

2)发布订阅模型

It works as follows:

它的工作原理如下:

  • (client first requests and shows some initial state)
  • client subscribes to the server (sends one request, possibly with some context like event source)
  • server marks the reference to the client to some its client reference repository
  • in case of an update of the state, server sends a notification to the client based on the reference to the client it holds; i.e. it is not a response to a request but a message initiated by the server
  • good clients unsubscribe when they are no more interested in the notifications
  • (客户端首先请求并显示一些初始状态)
  • 客户端订阅服务器(发送一个请求,可能带有一些上下文,如事件源)
  • 服务器将客户端的引用标记为其某个客户端引用存储库
  • 在状态更新的情况下,服务器根据对它持有的客户端的引用向客户端发送通知;即它不是对请求的响应,而是由服务器发起的消息
  • 好的客户在对通知不再感兴趣时取消订阅

This is SSE, or within threading a waitable event, as another example. A natural drawback, as stated, is that the server must know about all its subscribed clients which, depending on an implementation, can be an issue.

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