javascript 高效重载数据/将数据从服务器推送到客户端

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16122911/
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-10-27 03:20:52  来源:igfitidea点击:

Efficient reloading data / pushing data from server to client

phpjavascriptstreamclient-servercomet

提问by

I'm looking for the 'way to go' (i.e. the most efficient, most used, general accepted way) when it comes to the reloading of data from a web server to a front end. In the end application, I will have several output fields where data has to be written to, for example like this:

在将数据从 Web 服务器重新加载到前端时,我正在寻找“可行的方法”(即最有效、最常用、最普遍接受的方法)。在最终的应用程序中,我将有几个必须写入数据的输出字段,例如:

enter image description here

在此处输入图片说明

The data streams will be differentfrom each other in the end application. The lines will have to be reloaded with fresh, up to date data from the server.

最终应用程序中的数据流将彼此不同。必须使用来自服务器的最新数据重新加载线路。

I have been thinking of using Ajax requests to update like every second, but there has to be an other way to do this. Ajax requests will cause a lot data traffic. Also, when using the Facebook chat, you don't have to wait every second, chats are received almost instantly. Yet I don't see any Ajax polling requests being made when I use the developer tools of Mozilla Firefox. This made me think if there would be a different way to do this.

我一直在考虑使用 Ajax 请求来像每秒更新一样,但必须有其他方法来做到这一点。Ajax 请求会造成大量的数据流量。此外,在使用 Facebook 聊天时,您不必每一秒都在等待,几乎可以立即收到聊天内容。然而,当我使用 Mozilla Firefox 的开发人员工具时,我没有看到任何 Ajax 轮询请求。这让我思考是否会有不同的方法来做到这一点。

I've looked into Node.js, but it appears that isn't possible with my host.

我已经研究过 Node.js,但我的主机似乎不可能。

I have heard people talking about Ajax Push, is that what I should use? If so, can you give me a basic usage example?

我听说有人在谈论 Ajax Push,那是我应该使用的吗?如果是这样,你能给我一个基本的使用例子吗?

If not, what would thenbe the way to go when having multiple data streams that have to be reloaded within a second?

如果不是,那么当有多个数据流必须在一秒钟内重新加载时,该怎么办?

Requirements are speedand low data traffic. It therefore wouldn't be an option to continuously poll the server, I think, because that would create an enormous overhead.

要求是速度低数据流量。因此,我认为连续轮询服务器不是一种选择,因为这会产生巨大的开销。

I don't think it's of any importance, but I'm using PHP5.3 in the back end and JavaScript with jQuery 1.9.1 in the front end.

我认为这并不重要,但我在后端使用 PHP5.3,在前端使用 JavaScript 和 jQuery 1.9.1。

采纳答案by leggetter

This question has been asked a number of times, but in a slightly different ways. Here are a few references that are worth a read:

这个问题已经被问过很多次了,但方式略有不同。以下是一些值得一读的参考资料:

In summary: if you are looking at building your solution using PHP on Apache then holding open persistent connections (HTTP long-polling or streaming) is going to use up resources very quickly (is highly inefficient). So, you would be better using a hosted solution(*disclaimer - I work for a hosted solution).

总之:如果您正在考虑在 Apache 上使用 PHP 构建您的解决方案,那么保持开放的持久连接(HTTP 长轮询或流媒体)将很快耗尽资源(效率极低)。因此,您最好使用托管解决方案(*免责声明 - 我为托管解决方案工作)。

HTTP-Long polling and HTTP Streaming are solutions which have been superseded by Server-Sent Events and WebSockets. So, where possible (where the web client provides support) you should use one of these solutions before falling back to an HTTP-based solution. A good realtime web technology will automatically handle this for you.

HTTP-Long polling 和 HTTP Streaming 是已被 Server-Sent Events 和 WebSockets 取代的解决方案。因此,在可能的情况下(在 Web 客户端提供支持的情况下),您应该在回退到基于 HTTP 的解决方案之前使用这些解决方案之一。一个好的实时网络技术会自动为你处理这个。

Since your diagram shows you are subscribing to multiple data streams you should also consider a Publish/Subscribesolution that naturally fits with this. Again, a good realtime web tech solution will provide you with this.

由于您的图表显示您正在订阅多个数据流,因此您还应该考虑自然适合此的发布/订阅解决方案。同样,一个好的实时网络技术解决方案将为您提供这一点。

Also see the realtime web technology guide.

另请参阅实时 Web 技术指南

回答by angelatlarge

I think what you are looking for is generally called Comet. The was this technique is often made to work is as follows:

我认为您正在寻找的通常称为Comet。这种技术经常被使用如下:

  • The client (web browser) makes a request to the server for new data. This is not reloading the page, but rather is done in JavaScript
  • The server responds to the request when it has some data for the client. Again, this doesn't impact the UI since it isn't the page itself that's getting reloaded: the loaindg of data is done "in background" so to speak, in JavaScript code.
  • On the serve side, the request waits for new data, and returns the new data when available, or returns nothing if a timeout interval (defined on the server) is reached. This timeout is usually set to be lower than the browser HTTP timeout. The reason for this is so that the server can know whether a particular client got a particular piece of data. If the request is allowed to time out on the client side, the original request might be responded to by the server after the client has timed out, and the client will not get the data, even though the server thinks that it did.
  • 客户端(Web 浏览器)向服务器请求新数据。这不是重新加载页面,而是在 JavaScript 中完成
  • 当服务器有一些数据给客户端时,它会响应请求。同样,这不会影响 UI,因为重新加载的不是页面本身:数据的加载是在“后台”完成的,可以说是在 JavaScript 代码中。
  • 在服务端,请求等待新数据,并在可用时返回新数据,如果达到超时间隔(在服务器上定义),则不返回任何内容。此超时通常设置为低于浏览器 HTTP 超时。这样做的原因是服务器可以知道特定客户端是否获得了特定数据。如果在客户端允许请求超时,那么在客户端超时后,原始请求可能会被服务器响应,客户端将无法获取数据,即使服务器认为它确实做到了。

The data is indeed usually transferred as JSON, but you can choose whatever encoding you'd like. See herefor one example of how to do this. Gooshis another example of this technique, and so is Interactive Python Shell. The code for all is available.

数据确实通常以 JSON 格式传输,但您可以选择任何您喜欢的编码。有关如何执行此操作的示例,请参见此处Goosh是这种技术的另一个例子,交互式 Python Shell也是如此。所有代码都可用。



On the PHP side you will want to create a page that will respond to these "background" JavaScript Comet requests. It could be the same page as the one that user loads, but let's say it is different, for ease of explanation. So the user loads index.phpand the JavaScript Comet code calls getNewData.phpto retrieve new data.

在 PHP 端,您需要创建一个页面来响应这些“背景”JavaScript Comet 请求。它可能与用户加载的页面相同,但为了便于解释,我们假设它不同。因此,用户加载index.php并调用 JavaScript Comet 代码getNewData.php以检索新数据。

In your getNewData.phpyou will want to wait for your event and return the data then. You don't want to use polling for this, but there are PHP libraries that allow one to use various interprocess communication strategies to wait on events, see this question for instance. The high-level pseudocode for your getNewData.phpwould look as follows:

在您中,getNewData.php您将需要等待您的事件并返回数据。您不想为此使用轮询,但是有 PHP 库允许使用各种进程间通信策略来等待事件,例如参见这个问题。您的高级伪代码getNewData.php如下所示:

  1. parse JSON request
  2. Enter an efficient wait state (with timeout), waiting for your "new data is available" event
  3. Did previous step time out?
    Yes: send response indicating no data
    No: send response with new data
  1. 解析 JSON 请求
  2. 进入高效的等待状态(带超时),等待你的“新数据可用”事件
  3. 上一步是否超时?
    是:发送响应指示无数据
    否:发送带有新数据的响应