当前位置: 首页 > 面试题库 >

长轮询/ HTTP流一般问题

仰钧
2023-03-14
问题内容

我正在尝试使用php和jquery制作一个理论上的Web聊天应用程序,我已经阅读了有关长时间轮询和HTTP流的知识,并且设法运用了文章中介绍的大多数原理。但是,有两个主要问题我仍然无法解决。

长轮询

  • 服务器将如何知道何时发送更新?是否需要连续查询数据库或有更好的方法?

使用HTTP流

  • 在Ajax连接仍处于活动状态时,如何检查结果?我知道jQuery的successajax调用功能,但是如何在连接仍在进行 检查数据?

感谢您提供的所有答复。


问题答案:

是的,类似彗星的技术通常在一开始会炸毁大脑-
只是让您以不同的方式思考。另一个问题是PHP没有足够的可用资源,因为每个人都使用node.js,Python,Java等编写Comet。

我将尽力回答您的问题,希望它能为人们阐明这个话题。

服务器将如何知道何时发送更新?是否需要连续查询数据库或有更好的方法?

答案是:在最一般的情况下,您应该使用消息队列(MQ)。Redis商店中内置的RabbitMQ或Pub /
Sub功能可能是一个不错的选择,尽管市场上有许多竞争解决方案,例如ZeroMQ,Beanstalkd等。

因此,您可以只 订阅 一个MQ事件并挂起,直到其他人将 发布
您订阅的消息,而MQ会唤醒您并发送消息,而不是连续查询数据库。聊天应用程序是了解此功能的一个很好的用例。

我还要提到,如果您要搜索其他语言的Comet-
chat实现,您可能会注意到简单的不使用MQ的实现。那么他们如何交换信息呢?关键是这类解决方案通常实现为独立的单线程异步服务器,因此它们可以将所有连接存储在线程本地数组(或类似的东西)中,在单个循环中处理许多连接,只选择一个并在需要时通知。这种异步服务器实现是一种非常适合彗星技术的现代方法。但是,您很可能在mod_php或FastCGI之上实现Comet,在这种情况下,这种简单方法不是您的选择,您应该使用MQ。

这对于了解如何实现独立的异步Comet服务器以处理单个线程中的许多连接仍然非常有用。PHP的最新版本支持Libevent和Socket
Streams,因此也可以在PHP中实现这种服务器。PHP文档中还有一个示例。

在Ajax连接仍处于活动状态时,如何检查结果?我知道jQuery的ajax调用成功功能,但是如何在连接仍在进行时检查数据?

如果您使用普通的Ajax技术(例如纯XHR,jQuery
Ajax等)进行长时间的民意测验,那么您将没有简单的方法在单个Ajax请求中传输多个响应。正如您所提到的,您只有“成功”处理程序来整体处理响应,而不能部分处理。作为一种解决方法,人们每个请求仅发送一个响应,并在“成功”处理程序中对其进行处理,之后,他们只需打开一个新的长轮询请求即可。这就是HTTP协议的工作方式。

还应该提到的是,实际上存在一种变通办法,可以使用各种技术(例如隐藏中的无限长页面IFRAME或使用多部分HTTP响应)使用各种技术来实现类似流的功能。这两种方法都有一定的缺点(前一种方法被认为不可靠,有时可能会产生不必要的浏览器行为,例如无限的加载指示器,而后一种则泄漏了一致且直接的跨浏览器支持,但是已知某些应用程序仍然可以成功地依靠该方法当浏览器无法正确处理多部分响应时,该机制将退回到长轮询)。

如果您想以一种可靠的方式处理每个请求/连接的多个响应,则应考虑使用更先进的技术,例如WebSocket,该技术受最新浏览器支持,或在任何支持原始套接字的平台(例如Flash或(例如,如果您是为移动应用开发的)。

您能否详细说明消息队列?

Message
Queue是一个术语,用于描述Observer模式的独立(或内置)实现(也称为“发布/订阅”或简称为PubSub)。如果您开发一个大型应用程序,那么拥有一个应用程序将
非常 有用-
它使您可以解耦系统的不同部分,实现事件驱动的异步设计,并使您的生活变得更加轻松,尤其是在异构系统中。它在现实世界的系统中有许多应用程序,我将仅提及其中的几个:

  • 任务队列。假设我们正在编写自己的YouTube,并且需要在后台转换用户的视频文件。显然,我们应该有一个带有UI的web应用程序来上传电影,并使用固定数量的工作进程来转换视频文件(也许我们甚至需要一些专用服务器,我们的工作人员只会离开)。同样,我们可能必须用C语言编写工人,​​以确保获得更好的性能。我们要做的只是设置一个消息队列服务器,以收集视频转换任务并将其从Web应用程序传递给我们的工作人员。当工作程序生成时,它会连接到MQ,并空闲以等待新任务。当有人上传视频文件时,Web应用程序将连接到MQ并发布包含新作业的消息。强大的MQ,例如RabbitMQ 可以在连接的工作人员之间平均分配任务,跟踪已完成的任务,确保不会丢失任何内容,并提供故障转移甚至管理UI来浏览当前待处理的任务和统计信息。
  • 异步行为。我们的彗星聊天就是一个很好的例子。显然,我们不想一直都在定期轮询数据库(那么Comet的用途是什么?-进行定期Ajax请求的区别不大)。当出现新的聊天消息时,我们希望有人通知我们。一个消息队列就是那个人。假设我们正在使用Redis键/值存储-这是一个非常出色的工具,可以在其数据存储功能中提供PubSub实现。最简单的情况如下所示:
    1. 有人进入聊天室后,将发出新的Ajax长轮询请求。
    2. 服务器端的请求处理程序向Redis发出命令以订阅“ newmessage”通道。
    3. 一旦有人在聊天中输入消息,服务器端处理程序就会将消息发布到Redis的“ newmessage”主题中。
    4. 消息发布后,Redis将立即通知所有之前订阅该频道的未决处理程序。
    5. 收到通知后,保持长轮询请求打开的PHP代码可以返回请求并带有新的聊天消息,因此将通知所有用户。他们可以在那时从数据库中读取新消息,或者可以直接在消息有效负载内部传输消息。

我希望我的插图易于理解,但是消息队列是一个非常广泛的主题,因此请参考上面提到的资源以进一步阅读。



 类似资料:
  • 我试图使用一个永不关闭的HTTP流连接(这是Gnip合规流)。 我想使用HTTP工具包,但我无法让它工作。如果我传递参数: 在请求关闭之前,响应不会返回(并且永远不会完成)。 有办法做到这一点吗? 我在clj-超文本传输协议上也试过了,运气不好。

  • 问题内容: 我最近在StackOverflow上问了一个有关我的功能的问题,人们建议我使用Ajax Long Polling。我花了几天的时间研究该主题,并尝试编写基本的长轮询代码,但是这些代码都没有起作用,而且我什么也做不了。 这是我的基本功能: 有人能够告诉我如何将其转变为基本的长轮询功能,或者甚至直接指向我需要到达的路径。很感谢任何形式的帮助。谢谢! 问题答案: 通常(即,当不使用长时间轮询

  • 长轮询在GCP PubSub JS SDK上可用吗? 我希望能够同时处理多个PubSub消息,例如: 这是它将如何在AWS上工作的一个示例: SQS队列包含超过5条消息。 侦听器将在单个中一次获得5条消息。事件

  • 长轮询是与服务器保持持久连接的最简单的方式,它不使用任何特定的协议,例如 WebSocket 或者 Server Sent Event。 它很容易实现,在很多场景下也很好用。 常规轮询 从服务器获取新信息的最简单的方式是定期轮询。也就是说,定期向服务器发出请求:“你好,我在这儿,你有关于我的任何信息吗?”例如,每 10 秒一次。 作为响应,服务器首先通知自己,客户端处于在线状态,然后 —— 发送目

  • 问题内容: 我正在研究ajax长期轮询,但感到困惑。传统的ajax调用和长时间轮询有什么不同 此示例仅以递归方式调用服务器。与setInterval中的传统调用不同。 问题答案: 顾名思义,“ 长时间轮询” 意味着长时间轮询某些内容。 这是实际过程的开始,您对服务器上的某个脚本进行ajax调用,在本例中为,您需要使服务器脚本(例如)足够智能,以便仅在所需数据可用时才响应请求,该脚本应等待指定的时间

  • 问题内容: 使连接保持打开状态,直到发生事件。 python django http rest 问题答案: 显然,最常见的方法不是直接在django中进行,而是借助附加的守护程序(可能是因为,例如Apache在许多长寿命连接方面做得不好)。如今,nodejs + socketio对此非常流行(它甚至可以使用WebSockets)-您只需要找到一种在两种方法之间传递数据的好方法。如果它是单向的(例如