我正在尝试使用php和jquery创建一个理论上的Web聊天应用程序,已经阅读了有关长轮询和HTTP流的知识,并且设法运用了文章中介绍的大多数原理。但是,有两个主要问题仍然无法解决。
长轮询
使用HTTP流
success
函数,但是如何在连接仍在进行的同时检查数据? 我将不胜感激,谢谢您。
最佳答案
是的,类似 cometd 的技术通常在一开始会炸毁大脑-只是让您以不同的方式思考。另一个问题是PHP没有足够的可用资源,因为每个人都在使用node.js,Python,Java等编写Comet。
我将尽力回答您的问题,希望它能为人们阐明这个话题。
How will the server know when an update have been sent? will it need to query the databse continually or is there a better way?
答案是:在最一般的情况下,您应该使用消息队列(MQ)。 Redis商店中内置的RabbitMQ或Pub/Sub功能可能是一个不错的选择,尽管市场上有许多竞争解决方案,例如ZeroMQ,Beanstalkd等。
因此,您可以只订阅一个MQ事件并挂起,直到其他人将发布您订阅的消息,而MQ会唤醒您并发送消息,而不是连续查询数据库。聊天应用程序是了解此功能的一个很好的用例。
我还要提到的是,如果您要搜索其他语言的Comet-chat实现,您可能会注意到简单的不使用MQ的实现。那么他们如何交换信息呢?关键是这类解决方案通常实现为独立的单线程异步服务器,因此它们可以将所有连接存储在线程本地数组(或类似的东西)中,在单个循环中处理许多连接,只选择一个并在需要时通知。这样的异步服务器实现是一种非常适合 cometd 技术的现代方法。但是,您最有可能在mod_php或FastCGI之上实现Comet,在这种情况下,这种简单方法不是您的选择,您应该使用MQ。
这对于理解如何实现独立的异步Comet服务器以处理单个线程中的许多连接仍然非常有用。 PHP的最新版本支持Libevent和Socket Streams,因此也可以在PHP中实现这种服务器。 PHP文档中还有一个example。
How do I check for the results during the Ajax connection is still active? I'm aware of jQuery's success function for ajax calls, but how do I check the data while the connection is still ongoing?
如果您使用普通的Ajax技术(例如纯XHR,jQuery Ajax等)进行长时间的民意测验,那么您将没有简单的方法在单个Ajax请求中传输多个响应。如您所提到的,您只有“成功”处理程序来整体处理响应,而不能部分处理。解决方法是,每个请求仅发送一个响应,并在“成功”处理程序中对其进行处理,之后,他们只需打开一个新的长轮询请求即可。这就是HTTP协议(protocol)的工作方式。
还应该提到的是,实际上存在一种变通办法,可以使用各种技术(例如隐藏的
IFRAME
中的无限长页面或使用多部分HTTP响应)使用各种技术来实现类似于流的功能。这两种方法都有某些缺点(前一种方法被认为不可靠,有时可能会产生不必要的浏览器行为,例如无限加载指示符,而后一种则泄漏了一致且直接的跨浏览器支持,但是已知某些应用程序仍然可以成功地依靠该方法当浏览器无法正确处理多部分响应时,该机制会退回到长轮询)。如果您希望以一种可靠的方式处理每个请求/连接的多个响应,则应考虑使用更先进的技术,例如WebSocket,该技术受最新浏览器支持,或在任何支持原始套接字的平台(例如Flash或(例如,如果您是为移动应用开发的)。
Could you please elaborate more on message queues?
Message Queue是描述Observer pattern的独立(或内置)实现的术语(也称为“发布/订阅”或简称为PubSub)。如果您开发一个大型应用程序,那么拥有一个应用程序将非常有用-它使您可以解耦系统的不同部分,实现事件驱动的异步设计,并使您的工作变得更加轻松,尤其是在异构系统中。它在现实世界的系统中有许多应用程序,我将仅提及其中的几个:
我希望我的插图易于理解,但是消息队列是一个非常广泛的主题,因此请引用上面提到的资源以进一步阅读。
关于php - 长轮询/HTTP流一般问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7213549/