Ajax 长轮询限制

Posted

技术标签:

【中文标题】Ajax 长轮询限制【英文标题】:Ajax Long Polling Restrictions 【发布时间】:2012-05-17 03:53:00 【问题描述】:

所以我和一个朋友正在构建一个基于 Web 的、带有 jQ​​uery 和 php 核心的 AJAX 聊天软件。到目前为止,我们一直在使用标准程序,即每两秒左右调用一次服务器以查找更新。但是我开始不喜欢这种方法,因为它速度不快,而且即使没有数据返回,也有大量的请求从服务器来回传输,也不是“成本效益高”。

我们的一位项目支持者建议我们研究一种称为 COMET 的技术,或者更具体地说,长轮询技术。然而,在阅读了不同文章和博客文章中的相关内容后,我发现它在与 Apache 服务器一起使用时并不是那么实用。似乎大多数人只是说“这不是一个好主意”,但并没有提供太多关于 Apache 一次可以处理多少个请求的细节。

PureChat 的全部目的是为人们提供一个看起来很棒、速度很快且适用于大多数服务器的聊天。因此,我假设我们大约 96% 的用户将使用 Apache,而不是 Lighttpd 或 nginx,它们被认为更适合长轮询。

切入正题:

在您看来,继续使用 setInterval 并重复请求新数据会更好吗?还是使用长轮询更好,尽管大多数用户将使用 Apache?此外,可以更具体地了解在 Apache 服务器发生故障并死机之前大约有多少人可以使用聊天?

【问题讨论】:

Tomcat 7 最新添加了对 WebSockets 的支持,因此请考虑将轮询后备作为另一种选择。 如果这是小规模的,这应该不是问题。如果您计划有 1000 多个并发用户,Apache 将会死掉,因为对于每个连接,它都会打开一个新线程,这会消耗大量内存。 NginX 在单个线程上运行,因此它可以扩展到多个连接。但是,如果您使用的是 PHP,那么在许多情况下,这对您的帮助并没有您想象的那么大。有关详细信息,请参阅我的以下答案。 【参考方案1】:

正如 Andrew 所说,套接字连接是与服务器进行异步通信的终极解决方案,尽管目前只有最先进的浏览器支持 WebSockets。 socket.io 是您可以使用的开源 API,如果浏览器支持它,它将启动 WebSocket 连接,但如果浏览器不支持它,它将回退到 Flash 替代方案。然而,这对于使用 API 的编码人员来说是透明的。

Socket 连接基本上保持浏览器和服务器之间的开放式通信,以便彼此可以随时相互发送消息。套接字服务器守护进程会保存一个已连接订阅者的列表,当它收到来自其中一个订阅者的消息时,它可以立即将此消息发送回所有订阅者。

但是,对于套接字连接,您需要一个在您的服务器上全时运行的套接字服务器守护程序。虽然这可以通过命令行 PHP(不需要 Apache)来完成,但它更适合 node.js 之类的东西,一个非阻塞的服务器端 javascript api。

node.js 也更适合您所说的长轮询。基本上 node.js 是事件驱动和单线程的。这意味着您可以保持许多连接打开,而不必打开尽可能多的线程,这会占用大量内存(Apaches 问题)。这允许高可用性。但是,您必须记住的是,即使您使用的是 Nginx 之类的非阻塞文件服务器,PHP 也有许多阻塞网络调用。由于它在单个线程上运行,因此每个(例如)mysql 调用基本上都会停止服务器,直到返回对该 MySQL 调用的响应。发生这种情况时,其他任何事情都不会完成,从而使您的非阻塞服务器无用。但是,如果您使用 JavaScript (node.js) 等非阻塞语言进行网络调用,这将不是问题。它不会等待来自 MySQL 的响应,而是设置一个处理函数来在响应可用时处理响应,从而允许服务器在等待时处理其他请求。

对于长轮询,您基本上会发送一个请求,服务器会等待 50 秒后再响应。如果它有任何要报告的内容,它将在 50 秒内响应,否则它会等待。如果 50 秒后没有任何报告,它无论如何都会发送响应,这样浏览器就不会超时。该响应将触发浏览器发送另一个请求,并且该过程重新开始。这允许更少的请求和更快速的响应,但同样不如套接字连接。

【讨论】:

另外,请记住,套接字服务器守护进程需要访问您服务器的套接字,而共享服务器上通常不允许这样做。你需要一个 VPS。 感谢您的详细回复。非常感谢。我在这里基本上面临的问题是,由于我们将聊天作为开源软件发布,我们无法控制将安装它的服务器。鉴于此,我们必须假设绝大多数用户将使用共享主机。因此,他们可能无法访问套接字,也可能不会安装 Node.js。您认为我们实施具有用户限制/上限的长轮询会更好,这样事情就不会失控吗? 老实说,我不太确定。正如您所说,不同的服务器具有不同的内存量。我在谷歌上快速搜索了返​​回剩余内存量的 PHP 函数。我得到的只是返回所用内存量的函数。 websockets 的任何替代方案?

以上是关于Ajax 长轮询限制的主要内容,如果未能解决你的问题,请参考以下文章

Tornado-长轮询_webSocket

用大白话揭开Ajax长轮询(long polling)的神秘面纱

Ajax 长轮询

求教,django与长轮询,该怎么解决

ajax长轮询

Django,Ajax 长轮询,Postgresql:空闲事务