短轮询 vs 长轮询:实时Web应用的选择?

100

我正在构建一个实时Web应用程序,据我所知,最流行的选择是短轮询和长轮询。在选择其中一种方式时,可能存在哪些优缺点?

我正在开发一个实时的Web应用程序。据我所知,短轮询和长轮询是最常见的选择。选择哪种方式会有什么优缺点呢?请注意,本文不会对技术进行解释。

6
"长轮询"已经存在了,只是不是通过websockets实现的。您仍然可以使用iframe/script/xhr来保持与服务器的连接而不被关闭。 - Hemlock
4
如果有其他人正在研究这个话题,这里有一个关于“短轮询与长轮询”的问题short-polling vs long-polling - blong
3个回答

127

仅为了论证而言。

两者都是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的可用内存(空闲)。假设您每个php实例使用25 MB,那么您只能获得最多40个长轮询连接脚本。

这正是为什么您可以使用Node为很多内容提供服务的原因,因为Node不会生成其实例(除非您要使用工作程序等),因此使用相同的内存,您很可能可以轻松达到10k个连接挂起。当它们来时,您会得到CPU的飙升,并且当它们处于闲置状态时,就好像它们不存在一样(您只支付在节点/ c++中保留的内存结构)。

Websocket

现在,如果您想发送一些东西,无论何时客户端进入或退出,请选择websocket(ws协议)。第一个调用是http请求的大小,但稍后您仅发送消息,从客户端到服务器(新问题)和服务器到客户端(答案或推送-甚至可以为所有连接的客户端执行广播)。有php websocket库,但再次,请使用一些不同的技术-最好是Node或C ++。

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

何时使用

短轮询- 从来没有^^。

长轮询- 可能是当您正在与服务器进行单个调用交换,并且服务器正在后台执行某些工作时。也适用于您不再在同一页上查询服务器的情况。还有当您不使用php作为处理长轮询连接的中间层时,长轮询可能确实很有益处(Node / C ++可以是简单的中间层)。请注意,只有使其如此时,长轮询才可能真正有利。

Websocket- 您可能会与服务器交换多个调用,或者可能会收到您未预期/请求的来自服务器的内容,例如电子邮件通知等。根据功能计划不同的“房间”。拥抱基于事件的JavaScript特性;]


5
基本上,长轮询是一个持久连接,可以是异步打开的套接字,而短轮询通常是同步过程的永久请求。 - Joseph Persico
1
它本身并不是持久的,而是因为你没有立即从服务器发送响应,一旦你这样做了,它就会关闭 - 换句话说,它在等待(挂起)。与某些长时间的cron脚本相同的行为 - 它们只会在准备好后10分钟后向浏览器发送内容。原理是相同的 - 只是使用方式不同。所以它非常同步。这也带来了长轮询的第二个问题,我没有提到 - 浏览器限制打开连接的数量(现在大约为8个 - 目前浏览器中没有websocket连接的限制)。 - sp3c1
2
长轮询的另一个严重限制是会话锁定,除非关闭会话或使用非阻塞会话管理器(如db),否则用户的会话文件将被锁定,并且即使从不同的浏览器窗口也无法接受用户的请求。 - jvrnt
7
短轮询在仪表盘应用程序中有其重要作用,由于批量UI更新的架构和用户体验优势。 - nicodjimenez
2
哪个最容易扩展? - fatfrog

80
  • 短轮询(也称为基于 AJAX 的定时器):

    优点:较简单,不会占用服务器资源(如果请求之间的时间较长)。
    缺点:如果您需要在没有延迟的情况下被通知服务器事件发生,那么效果不佳。 示例(基于ItsNat

  • 长轮询(也称为基于 Comet 的 XHR)

    优点:您将在没有延迟的情况下被通知服务器事件的发生。 缺点:更复杂,使用更多服务器资源。 示例(基于 ItsNat)


28
对于长轮询,服务器的主要限制资源是最大开放套接字数。不同操作系统有不同的限制,但都存在限制,而且这些限制远低于可用内存。短轮询可以避免这一问题,因为每个连接仅在短时间内打开,因此可以对许多连接进行时间复用。 - slebetman
长轮询并不会使用更多的资源,事实上它使用的资源要少得多。一个空闲的套接字连接基本上除了保持活动数据包(如果启用/配置)和一个打开的文件描述符之外,几乎不使用任何资源。 - Nepoxx
2
示例不再可用。 - Diego Queiroz

2
如果您想获得基于数据库的实时应用程序,可以使用ajax长轮询和comet组合。 长轮询对带宽非常有益,对用户MB也非常有用。因为当用户发送请求时,用户将支付类似MB或某种互联网连接的费用。例如,对于短轮询,如果您执行每秒钟发送请求的操作,则用户的互联网使用量将更多,因为每个连接用户都会为此付费(这意味着用户失去Mb),但是在长轮询中,用户仅需支付新消息的费用。
Websocket确实是一件好事,但是当您使用它时,您应该考虑到一个大问题,即许多人无法使用聊天系统,因为Websocket仅适用于新版本的浏览器。

很多人应该更新他们的浏览器...Websockets已经在IE11上得到支持。微软正在推动所有人使用Windows 10,这意味着默认情况下使用Edge。除非你使用Opera Mini,但那是你的错 :P - Manatax
1
这就是为什么当Websockets不可用时,您应该使用像socket.io这样的东西来为您处理它;] 然而代码库保持不变。 - sp3c1
1
@sp3c1 Socket.io 是一个可扩展性的噩梦。 - Hobbyist
@sp3c1 很高兴听到这个消息,我能在共享主机中使用socket.io吗?因为websocket也有缺点,比如它不能在共享主机计划中工作。 - Ibrahim Hasanov
@sp3c1,我需要使用什么类型的托管来使用Websocket?VPS? - Ibrahim Hasanov
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接