浏览器会限制AJAX轮询率吗?限制是多少?

时间:2012-10-05 12:53:20

标签: ajax xmlhttprequest limit polling rate

我刚刚读到一些浏览器会阻止HTTP轮询(我想通过限制请求的速率)......

来自https://github.com/sstrigler/JSJaC

  

注意:由于大多数现代浏览器的安全限制都会阻止HTTP   轮询无法再使用此模块默认情况下处于禁用状态   现在。如果你想在使用'make polling'编译它。

这可以解释我的一些JavaScripts的一些不当行为(有时请求不会被发送或重试,即使它们实际上是成功的)。但我无法找到有关细节的更多信息..

问题

  • 如果是“每x秒最多请求数n”,x和n的常用/默认设置是什么?
  • 这有什么好的资源吗?
  • 是否有任何方法可以检测请求是否因速率限制而“延迟”或“拒绝”?

感谢您的帮助......

的Stefan

6 个答案:

答案 0 :(得分:4)

是的,据我所知,默认池限制为10,每个请求的默认请求超时为30秒,但是可以控制超时和轮询限制,并且不同的浏览器实现不同的限制!

查看此Google implementation

这是捕获超时错误的awesome implementation

您可以找到Firefox详细信息HERE

从Windows注册表中控制Internet Explorer细节。

另请查看this question

基本上,您控制的方式不是通过更改浏览器限制,而是通过遵守它们。因此,您应用了一种称为节流的技术。

将其视为创建函数的FIFO /优先级队列。将xhr请求作为成员并在它们之间强制执行延迟的队列结构是Xhr轮询。例如,我正在使用 Jsonp从位于另一个域的node.js服务器获取数据,当然由于浏览器限制我正在轮询。否则,我从服务器返回零响应,这只是因为浏览器的限制。

我实际上正在为每个应该发送的请求执行控制台日志,但并非所有请求都被记录。所以浏览器会限制它们。

我会更加具体地帮助你。我的网站上有一个页面,可以呈现几十甚至几百篇文章。你可以使用一个很酷的水平滑块来浏览它们。

滑块的当前值与当前页面相匹配'。由于我每页只显示5篇文章而且我无法准确加载数千篇文章' onload'没有严重的性能影响,我加载当前页面的文章。我通过向Python脚本发送跨域请求从MongoDB中获取它们。

该脚本应该返回一个包含五个对象的数组,其中包含构建“'页面”的DOM元素所需的所有详细信息。但是,有几个问题。

首先,滑块的工作速度非常快,因为它的价值变化或多或少。即使存在拖放功能,按键事件等,实际更改也需要几毫秒。但是,滑块的代码如下所示:

goog.events.listen(slider, goog.events.EventType.CHANGE, function() {
    myProject.Articles.page(slider.getValue());
}

slider.getValue()方法返回一个带有当前页码的int,所以基本上我必须加载:

currentPage * articlesPerPage to (currentPage * articlesPerPage + 1) - 1

但是为了加载,我做这样的事情: 我有一个存储引擎(把它想象成一个数组):

  • 我检查内容是否已经存在
  • 如果是,则没有必要再提出请求,所以继续从已经创建的DOM元素到数组中获取DOM元素。
  • 如果不是,那么我需要得到它,所以我需要发送我提到的请求,这看起来像(不考虑浏览器限制):

    JSONP.send({' action':' getMeSomeArticles'' start':start,' length':itemsPerPage,function(回调){

    //现在我只是快速解析回调以确保它是一致的 //创建DOM元素,并填充客户端存储 //并更新用户的视图。 }}

问题来自您可以更改滑块的速度。因为每个更改都应该触发一个请求(对于正常的Xhr请求也会发生这种情况),那么你基本上就是超越了所有浏览器的限制,所以没有节流,就不会有回调'对于大多数请求。 '回调'是JSONP请求返回的JS代码(更多的是远程脚本包含而不是其他任何东西)。

所以我所做的是将请求推送到优先级队列,而不是POLL,因为现在我不需要发送多个同时请求。如果队列为空,则执行最近添加的成员,每个人都很高兴。如果不是,那么所有未完成的请求都将被取消,只有最后一个请求被执行。

现在在我的特定情况下,我进行二进制搜索(0(log n))以查看存储引擎是否还没有先前请求的数据,这告诉我先前的请求是否已完成或不。如果有,则将其从队列中删除并处理当前的队列,否则新的队列将被触发。所以等等。

同样,为了速度考虑和糟糕的浏览器想要像Internet Explorer,我做了上述程序,前面提前3-4步。所以我预先加载20页,直到一切都是客户端存储引擎。这样,每个限制都能成功处理。

冷却时间由滑过20页所需的最短时间所涵盖,并且节流确保在任何给定时间不超过1个活动请求(向后兼容性与Internet Explorer 5相同) )。

我写这一切的原因是为了给你一个例子,试图说你不能总是直接从FIFO结构强制执行延迟,因为你的电话可能需要变成用户看到的内容,而你不要#39; t确切地想让用户等待10-15秒来渲染单个页面。

此外,始终最小化轮询和轮询的需要(同时触发Ajax事件,因为并非所有浏览器实际上都使用它们做好事)。例如,不是像发送一个请求来获取内容而是发送另一个请求以便在应用程序指标中查看要跟踪的内容,而是在服务器级别尽可能多地执行任务!

当然,您可能希望正确地跟踪错误,因此您选择的库中的Xhr对象会实现ajax的错误处理,因为您是一个非常棒的开发人员,您想要使用它们。

所以说你有一个尝试 - 捕获块到位 场景是这样的: Ajax调用已经完成,并且它应该返回一个JSON,但是调用以某种方式失败了。但是,您尝试解析JSON并执行您需要执行的操作。 所以

function onAjaxSuccess (ajaxResponse) {
    try {
        var yourObj = JSON.parse(ajaxRespose);
    } catch (err) {
    // Now I've actually seen this on a number of occasions, to log that an error occur
    // a lot of developers will attempt to send yet another ajax request to log the
    // failure of the previous one.
    // for these reasons, workers exist.
    myProject.worker.message('preferrably a pre-determined error code should go here');
    // Then only the worker should again throttle and poll the ajax requests that log the
    //specific error. 
};

};

虽然我已经看到各种实现尝试同时触发尽可能多的Xhr请求,直到它们遇到浏览器限制,然后做好拖延那些没有等待的问题。对于浏览器的冷却时间,我可以建议你考虑以下事项:

  • 您的应用的速度有多重要?
  • I / O的可扩展性和集中程度如何?

如果对第一个问题的回答是“非常”。对于后者的OMFG现代技术,然后尽可能地优化您的代码和架构,这样您就不需要同时发送10个Xhr请求。此外,对于大型应用程序,多线程您的流程。 JavaScript的实现方法是使用worker。或者您可以调用ECMA板,告诉他们将其设置为默认值,然后将其发布到此处以便我们其余的JS开发人员可以在JS中享受原生多线程:)(dafuq他们怎么没想到这个?! ?!)

答案 1 :(得分:3)

Stefan,快速回答如下:

- 如果它是“每x秒的最大请求数n”,x和n的常规/默认设置是什么? 这听起来更像是服务器限制。浏览器通常听起来像: - “对同一主机名的最大请求数为x” - “任何主机名的最大连接数为y”

- 这有什么好的资源吗? http://www.browserscope.org/?category=network(也将鼠标悬停在表格标题上以查看测量结果) http://www.stevesouders.com/blog/2008/03/20/roundup-on-parallel-connections

- 任何方法都可以检测请求是否因为速率限制而被“延迟”或“拒绝”? 您可以查看“连接:关闭”的http标头以检测服务器限制,但我不知道JavaScript能够以一致的,与浏览器无关的方式从这么多浏览器中读取设置。 (对于Firefox,您可以阅读此http://support.mozilla.org/en-US/questions/746848

希望这个快速回答有帮助吗?

答案 2 :(得分:2)

不,浏览器不会以任何方式影响轮询。我认为该页面的含义是相同的原始策略 - 您只能访问与原始页面相同的主机和端口。

只有连接本身的已知限制是您通常只能有两到四个同时连接到同一主机。

答案 3 :(得分:2)

我编写了一些带有长轮询的应用程序,其中一些使用我自己的网络服务器进行C ++后端,另一种使用带有Apache2的PHP后端。

我的长轮询超时是4..10秒。当发生某事或4..10秒后,我的服务器返回一个空响应。然后客户端立即启动另一个AJAX请求。我发现当我从之前的AJAX处理程序启动AJAX调用时,某些浏览器会挂起,所以我使用一个小值的setTimeout()来启动下一个AJAX请求。

当客户端发生某些事情(应该发送到服务器)时,我会使用另一个AJAX请求,但它是单向的:服务器不发送任何响应,客户端不处理任何事情。操作的结果(如果有的话)将在长轮询中收到。它需要最多。 2连接到服务器,所有浏览器都支持。

请记住,如果有500个客户端,则意味着500个服务器端网络服务器线程,它们将一起移动,发生负载峰值,因为当发生某些事情时,服务器必须同时为每个客户端报告它,客户端将在同一时间内处理它们,它们将在同一时间启动下一个长请求,从那时起,超时也将同时到期,并且即将到期。你可以使用rnd超时,例如4 rnd(0..4),但它没有价值,如果发生任何事情,它们将再次“同步”,所有请求必须在可报告事件发生时同时提供。 / p>

我通过路由器对它进行了测试,但它确实有效。我假设,路由器尊重4..10滞后,这是一个慢速webapge(远,远)的速度,没有路由器认为它应该被取消。

我的PHP工作是一个协作电子表格,当你点击输入并且在几个浏览器中同时更新内容时,它看起来很神奇。玩得开心!

答案 4 :(得分:1)

没有ajax请求的限制。然而,它将在同一主机&端口。

服务器可以根据设置限制来自计算机的请求。

例如。服务器可以设置为如果在指定时间内来自同一台机器的请求数量超过少,它将拒绝请求。

答案 5 :(得分:0)

在javascript代码中出现小错误之后,每个步骤调用2个ajax请求都会产生无休止的循环。在firebug中我可以看到越来越多的请求,直到firefox开始减速,不响应并最终崩溃。

所以,是的,有一个“限制”;)