实时 Web 应用程序的短轮询与长轮询?

IT技术 javascript http comet real-time long-polling
2021-02-05 06:40:59

我正在构建一个实时 Web 应用程序 据我所知,最流行的选择是短轮询和长轮询。衡量一个相对于另一个可能有哪些优点和缺点?

3个回答

只是为了辩论。

两者都是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 不会产生它的实例(除非您想使用工作程序等),因此使用相同的内存,您可能很容易挂起 10k 个连接。当它们出现时,您会在 CPU 中出现峰值,并且它们何时可能被释放,但是当它们空闲时,它们就像不在那里一样(您只需为将保留在 node/c++ 中的内存结构付费)。

网络套接字

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

一些库,比如 socket.io 有自己的层次结构,所以当 websocket 失败时,它会回到长轮询或短轮询。

何时使用。

短轮询- 好吧,永远不会^^。

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

Websocket - 您可能会与服务器交换一两个以上的调用,或者某些内容可能来自您不期望/询问的服务器,例如电子邮件通知或其他内容。您应该根据功能规划不同的“房间”。拥抱 javascript 基于事件的性质;]

哪个最容易扩展?
2021-03-18 06:40:59
由于批量 UI 更新的架构和 UX 优势,短轮询有其一席之地,例如在仪表板应用程序中。
2021-03-20 06:40:59
长轮询的另一个严重限制是会话锁定,除非您关闭会话或使用非阻塞会话管理器(如 db),否则用户的会话文件将被锁定并且不会接受来自用户的请求,即使来自不同的浏览器窗户。
2021-03-25 06:40:59
它不是持久的 - 它是你没有从服务器发送响应,等待 - 一旦你关闭它 - 换句话说,它正在等待(挂起)。使用一些长的 cron 脚本会得到相同的行为 - 仅在 10 分钟后准备好浏览器时发送内容。原理是一样的——只是用法有所变化。所以它非常同步。这也给你带来了我没有提到的长轮询的第二个问题——浏览器对打开连接数的限制(我认为现在大约是 8 个——浏览器中的 websocket 连接 atm 没有限制)。
2021-03-31 06:40:59
所以本质上,长轮询是可以异步打开套接字的持久连接,而短轮询通常是同步进程的永久请求?
2021-04-01 06:40:59
  • 短轮询(又名基于 AJAX 的计时器):

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

  • 长轮询(又名 Comet 基于 XHR)

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

特别是对于长轮询,主要限制服务器资源是打开套接字的最大数量。不同的操作系统有不同的限制,但有限​​制,而且这些限制远低于可用内存。短轮询可以解决这个问题,因为每个连接只打开一小段时间,因此可以对许多连接进行时间复用。
2021-03-31 06:40:59
示例不再可用。
2021-04-01 06:40:59
长轮询不会使用更多的资源,实际上它使用的资源要少得多。除了保持活动的数据包(如果启用/配置)和打开的文件描述符之外,空闲套接字连接基本上不使用任何资源。
2021-04-06 06:40:59

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

Websocket确实是个好东西,但是当你使用它时,你应该考虑一个大问题,很多人无法使用聊天系统,因为 Websocket 只是针对新版本的浏览器

@sp3c1 我很高兴听到这个消息,我可以在共享托管中使用 socket.io 吗?因为 websocket 也有缺点,比如它不能用于共享托管计划
2021-03-21 06:40:59
@sp3c1 Socket.io 是可扩展性的噩梦。
2021-03-23 06:40:59
@Hobbyist 怎么会这样?您可以负载平衡,现在您还可以在不同进程之间共享套接字。你总是可以回退到纯 websocket 实现,但核心保持不变。好吧,您可以自己进行套接字实现,但是对于 webdev 来说,这是一个很好的标准,为什么还要发明轮子呢?如果您在处理套接字连接的进程的分布式通信方面遇到问题,您可以随时探索 redis pub/sub。socket.io 超过 websocket 的真正优势是回退协议,这使它适用于旧浏览器。
2021-03-29 06:40:59
很多人应该更新他们的浏览器...... IE11 已经支持 Websockets。微软正在推动所有人进入 Windows 10,这意味着默认情况下 Edge。除非您使用的是 Opera Mini,否则那是您的错:P
2021-04-06 06:40:59
这就是为什么你应该使用像 socket.io 这样的东西,当 websockets 不可用时,它会为你处理这个;] 但代码库保持不变
2021-04-12 06:40:59