长轮询/HTTP流一般问题 [英] Long Polling/HTTP Streaming General Questions

查看:105
本文介绍了长轮询/HTTP流一般问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用,阅读有关长轮询和HTTP流的信息,我设法应用了文章中介绍的大多数原理.但是,有两个主要问题仍然无法解决.

I'm trying to make a theoretical web chat application with php and jquery, I've read about long polling and http streaming, and I managed to apply most principles introduced in the articles. However, there are 2 main things I still can't get my head around.

  • 服务器将如何知道何时发送更新?它需要连续查询数据库还是有更好的方法?
  • 如何在Ajax连接仍处于活动状态时检查结果?我知道jQuery的success函数用于ajax调用,但是如何在连接仍在进行的同时 检查数据?
  • 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?

我将不胜感激,感谢您.

I'll appreciate any and all answers, thanks in advance.

推荐答案

是的,像彗星一样的技术通常在一开始就让大脑大吃一惊-只是让您以不同的方式思考.还有一个问题是PHP没有足够的可用资源,因为每个人都在使用node.js,Python,Java等编写自己的Comet.

Yeah, the Comet-like techniques usually blowing up the brain in the beginning -- just making you think in a different way. And another problem is there are not that much resources available for PHP, cuz everyone's doing their Comet in node.js, Python, Java, etc.

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

I'll try to answer your questions, hope it would shed some light on this topic for people.

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

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等.

The answer is: in the most general case you should use a message queue (MQ). RabbitMQ or the Pub/Sub functionality built into the Redis store may be a good choices, though there are many competing solutions on the market available such as ZeroMQ, Beanstalkd, etc.

因此,您可以订阅以获得MQ事件,然后挂起直到其他人发布您订阅的消息,然后MQ即可继续查询数据库,而不用继续查询数据库.叫醒您并发送消息.聊天应用程序是理解此功能的很好的用例.

So instead of continuous querying your database, you can just subscribe for an MQ-event and just hang until someone else will publish a message you subscribed for and MQ will wake you up and send a message. The chat app is a very good use case to understand this functionality.

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

Also I have to mention that if you would search for Comet-chat implementations in other languages, you might notice simple ones not using MQ. So how do they exchange the information then? The thing is such solutions are usually implemented as standalone single-threaded asynchronous servers, so they can store all connections in a thread local array (or something similar), handle many connections in a single loop and just pick a one and notify when needed. Such asynchronous server implementations are a modern approach that fits Comet-technique really great. However you're most likely implementing your Comet on top of mod_php or FastCGI, in this case this simple approach is not an option for you and you should use MQ.

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

This could still be very useful to understand how to implement a standalone asynchronous Comet-server to handle many connections in a single thread. Recent versions of PHP support Libevent and Socket Streams, so it is possible to implement such kind of server in PHP as well. There's also an example available in PHP documentation.

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

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协议的工作方式.

If you're doing your long-running polls with a usual Ajax technique such as plain XHR, jQuery Ajax, etc. you don't have an easy way to transmit several responses in a single Ajax request. As you mentioned you only have 'success' handler to deal with the response in whole and not with its part. As a workaround people send only a single response per request and process it in a 'success' handler, after that they just open a new long-poll request. This is just how HTTP-protocol works.

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

Also should be mentioned that actually there are workaround to implement streaming-like functionality using various techniques using techniques such as infinitely long page in a hidden IFRAME or using multipart HTTP-responses. Both of those methods are certain drawbacks (the former one is considered unreliable and sometimes could produce unwanted browser behavior such as infinite loading indicator and the latter one leaks consistent and straightforward cross-browser support, however certain applications still are known to successfully rely on that mechanism falling back to long-polling when the browser can't properly handle multipart responses).

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

If you'd like to handle multiple responses per single request/connection in a reliable way you should consider using a more advanced technology such as WebSocket which is supported by the most current browsers or on any platform that supports raw sockets (such as Flash or if you develop for a mobile app for instance).

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

Could you please elaborate more on message queues?

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

Message Queue is a term that describes a standalone (or built-in) implementation of the Observer pattern (also known as 'Publish/Subscribe' or simply PubSub). If you develop a big application, having one is very useful -- it allows you to decouple different parts of your system, implement event-driven asynchronous design and make your life much easier, especially in a heterogeneous systems. It has many applications to the real-world systems, I'll mention just couple of them:

  • 任务队列.假设我们正在编写自己的YouTube,并且需要在后台转换用户的视频文件.显然,我们应该有一个带有UI的Web应用程序来上传电影,并使用固定数量的工作进程来转换视频文件(也许我们甚至需要一些专用服务器,我们的工作人员只能离开这些服务器).同样,我们可能不得不用C语言编写我们的工作人员,以确保获得更好的性能.我们要做的只是设置一个消息队列服务器,以收集视频转换任务并将其从Web应用程序传递给我们的工作人员.当工作程序生成时,它会连接到MQ,并空闲以等待新任务.当有人上传视频文件时,Web应用程序将连接到MQ并发布包含新作业的消息.诸如 RabbitMQ 之类的强大MQ可以在连接的多个工作人员之间平均分配任务,跟踪已完成的任务,确保不会丢失任何任务并将提供故障转移甚至管理UI来浏览当前待处理的任务和统计信息.
  • 异步行为.我们的彗星聊天就是一个很好的例子.显然,我们不想一直都在定期轮询数据库(那么Comet的用途是什么?-进行定期Ajax请求的区别不大).当出现新的聊天消息时,我们希望有人通知我们.一个消息队列就是那个人.假设我们正在使用 Redis 键/值存储-这是一个非常不错的工具,它提供了
  • Task queues. Let's say we're writing our own YouTube and need to convert users' video files in the background. We should obviously have a webapp with the UI to upload a movie and some fixed number of worker processes to convert the video files (maybe we would even need a number of dedicated servers where our workers only will leave). Also we would probably have to write our workers in C to ensure better performance. All we have to do is just setup a message queue server to collect and deliver video-conversion tasks from the webapp to our workers. When the worker spawns it connects to the MQ and goes idle waiting for a new tasks. When someone uploads a video file the webapp connects to the MQ and publishes a message with a new job. Powerful MQs such as RabbitMQ can equally distribute tasks among number of workers connected, keep track of what tasks had been completed, ensure nothing will get lost and will provide fail-over and even admin UI to browse current tasks pending and stats.
  • Asynchronous behavior. Our Comet-chat is a good example. Obviously we don't want to periodically poll our database all time (what's the use of Comet then? -- Not big difference of doing periodical Ajax-requests). We would rather need someone to notify us when a new chat-message appears. And a message queue is that someone. Let's say we're using Redis key/value store -- this is a really great tool that provides PubSub implementation among its data store features. The simplest scenario may look like following:
  1. 有人进入聊天室后,将发出新的Ajax长轮询请求.
  2. 服务器端的请求处理程序向Redis发出命令以订阅"newmessage"频道.
  3. 一旦有人在聊天中输入一条消息,服务器端处理程序就会在Redis的"newmessage"主题中发布一条消息.
  4. 消息发布后,Redis将立即通知之前订阅该频道的所有待处理处理程序.
  5. 通知后,保持长时间轮询请求打开的PHP代码可以返回带有新聊天消息的请求,因此将通知所有用户.他们此时可以从数据库中读取新消息,或者可以直接在消息有效负载内部传输消息.

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

I hope my illustration is easy to understand, however message queues is a very broad topic, so refer to the resources mentioned above for further reading.

这篇关于长轮询/HTTP流一般问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆