实时网络应用程序的短轮询还是长轮询?


73

我正在构建一个实时Web应用程序据我所知,最受欢迎的选择是短轮询和长轮询。测量一个比另一个可能会有什么优点和缺点?


6
@metrobalderas长轮询在这里,只是不像websockets。您仍然可以使用iframe / script / xhr并阻止服务器关闭连接。
Hemlock

@metrobalderas:Google“ ajax彗星”
slebetman 2011年

3
对于其他研究此主题的人,这是关于短轮询与长轮询的另一个问题。
blong

Answers:


70
  • 短轮询(又名基于AJAX的计时器):

    优点:更简单,不消耗服务器(如果请求之间的时间很长)。
    缺点:如果您需要在服务器事件发生时没有延迟的情况下得到通知,则不好。 示例(基于ItsNat

  • 长轮询(又名基于XHR的彗星)

    优点:服务器事件立即发生时会通知您。缺点:更复杂,使用的服务器资源更多。 示例(基于ItsNat)


25
专门用于长时间轮询的主要限制服务器资源是打开的套接字的最大数量。不同的操作系统具有不同的限制,但是存在限制,并且这些限制比可用内存低得多。短轮询可以解决此问题,因为每个连接仅在短时间内打开,因此许多连接可以进行时间复用。
slebetman 2011年

长轮询不使用更多资源,实际上它使用的资源要少得多。空闲套接字连接基本上不使用其他资源,而保持活动数据包(如果已启用/配置)和打开文件描述符除外。
Nepoxx

83

只是为了争辩。

两者都是http请求(xhr),并且至少部分不正确,它使用了更多的服务器资源(完全取决于技术,将在后面解释)。

短轮询。

它们在服务器上时处理的许多请求。创建大量流量(使用资源,但一旦发送回响应就将其释放):

00:00:00 C-> Is the cake ready? 
00:00:01 S-> No, wait.
00:00:01 C-> Is the cake ready?
00:00:02 S-> No, wait.
00:00:02 C-> Is the cake ready? 
00:00:03 S-> Yes. Have some lad.
00:00:03 C-> Is the other cake ready? ..

长时间轮询

一个请求发送到服务器,客户端正在等待响应(未解决)。如果服务器使用php / apache,则意味着将生成一个要处理的线程,该线程将保留资源,直到完成。因此,流量较小,但是您会很快耗尽资源(或者阻塞资源)。但是,如果您使用例如Node(或任何其他异步方法,例如c ++ qt),则可以最大限度地减少资源使用(存储http请求的响应对象,并在工作准备就绪时使用它)

12:00 00:00:00 C-> Is the cake ready? 
12:00 00:00:03 S-> Yes.Have some lad.
12:00 00:00:03 C-> Is the cake ready? 

如果将其与短轮询进行比较,您会发现在短轮询中您可能使用了更多的传输,但是在这3秒钟中,您实际上需要1.5秒钟的处理时间(意味着在两次调用之间可能执行某些操作)。如果进行长时间轮询,则始终使用相同的资源。现在通常所有库的php都以4MB内存开头-那么您有一个4-20MB的框架。假设您有1024MB RAM(免费)。说让我们感到悲观,并假设您将在每个php安装实例中使用25 MB。这意味着您最多只能获取40个长轮询连接脚本。

这正是为什么您可以使用Node提供更多服务的原因,因为Node不会生成其实例(除非您想使用worker等),因此,使用相同的内存,您可能很容易挂起10k连接。随着它们的到来,以及它们可能被释放时,您将在CPU上出现尖峰,但是当它们空闲时,它们就好像不在那里一样(您只为保留在node / c ++中的内存结构付费)。

Websocket

现在,如果您想发送一些东西,无论它们在客户端内外,请使用websockets(ws协议)。第一次调用是http请求的大小,但后来您只从客户端到服务器(新问题)和服务器到客户端(答案或推送-甚至可以为所有连接的客户端广播)发送消息。有php websocekts库,但是同样,请使用一些不同的技术-最好是node或c ++。

有些库(例如socket.io)具有其自己的层次结构,因此当websocket失败时,它会返回到长轮询或短轮询。

什么时候使用。

简短的轮询-好吧,永远不要^^。

长轮询-可能在您与服务器交换单个呼叫并且服务器在后台进行某些工作时。同样,当您不再在同一页面上查询服务器时。另外,当您不使用php作为处理长轮询连接的层时(node / c ++可以是一个简单的中间层)。请注意,长时间轮询确实很有用,但前提是您必须这样做。

Websocket-您可能会与服务器交换一两个电话,或者可能是您未曾希望/询问的服务器发出的消息,例如电子邮件通知或其他消息。您应该根据功能计划不同的“房间”。拥抱基于事件的javascript特性;]


3
因此,从本质上讲,长轮询是可以是异步开放套接字的持久连接,而短轮询通常是同步进程的永久请求?
2015年

1
它不是这样持久的-它不立即从服务器发送响应-并且一旦关闭它就发送-换句话说,它的等待(挂起)。使用一些较长的cron脚本,您会获得相同的行为-在准备好10分钟后,仅向浏览器发送内容。原理是相同的-它的用法不断变化。因此,它非常同步。这也给您带来了我没有提到的长轮询的第二个问题-浏览器对打开连接数的限制(我认为现在约为8个-浏览器中的websocket连接atm没有限制)。
sp3c1 2015年

2
长轮询的另一个严重限制是会话锁定,除非您关闭会话或使用非阻塞会话管理器(如db),否则用户的会话文件将被锁定,即使来自其他浏览器也不会接受来自用户的请求窗口。
jvrnt 2015年

3
由于批处理UI更新具有体系结构和UX的优点,因此可以在仪表板应用程序中使用短轮询。
nicodjimenez

1

如果要基于数据库获取实时应用程序,则可以使用ajax long poll和彗星组合。 长轮询是你的带宽非常好,也很为用户MB.Because真正有用的,当用户发送请求的用户将为此付出代价像MB或某种互联网connection.For例如对短调查,当你做这样的事情每发送请求第二个用户的互联网使用量将更多,因为每个连接用户都将为此付费(这意味着用户将释放Mb),但在长轮询中,用户只会为新消息付费。

Websocket确实是一件好事,但是当您使用Websocket时,您应该考虑一个大问题,很多人无法使用聊天系统,因为Websocket仅用于新版本的浏览器


很多人应该更新他们的浏览器... IE11已经支持Websockets。微软正在将所有人推向Windows 10,这意味着默认情况下为Edge。除非您使用Opera Mini,否则那是您的错:P
Manatax 2016年

1
这就是为什么您应该使用socket.io之类的方法在无法使用websockets时为您处理此问题;]但是代码库保持不变
sp3c1 2016年

@ sp3c1 Socket.io是可伸缩性的噩梦。
爱好者

@业余爱好者如何?您可以实现负载平衡,现在还可以在不同进程之间共享套接字。您总是可以退回到纯粹的websocket实现,但是核心保持不变。好了,您可以自己执行套接字实现,但是为什么对于webdev来说这是一个很好的标准,为什么还要发明轮子呢?如果处理套接字连接的进程的分布式通信存在问题,则可以随时浏览redis pub / sub。socket.io克服了websocket的真正优势是回退协议,这使其对旧的浏览器也无处不在。
sp3c1

@ sp3c1我很高兴听到这样的消息,我可以在共享托管中使用socket.io吗?因为websocket还具有缺点,例如它不能用于共享托管计划
Ibrahim Hasanov
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.