我可以找到很多关于长轮询如何工作的信息(例如,这个和这个),但没有简单的例子说明如何在代码中实现这一点。
我能找到的只有cometd,它依赖DojoJS框架和一个相当复杂的服务器系统。。
基本上,我将如何使用Apache来服务请求,以及我将如何编写一个简单的脚本(例如,用PHP)来“长轮询”服务器以获取新消息?
该示例不一定是可扩展的、安全的或完整的,它只需要工作即可!
我可以找到很多关于长轮询如何工作的信息(例如,这个和这个),但没有简单的例子说明如何在代码中实现这一点。
我能找到的只有cometd,它依赖DojoJS框架和一个相当复杂的服务器系统。。
基本上,我将如何使用Apache来服务请求,以及我将如何编写一个简单的脚本(例如,用PHP)来“长轮询”服务器以获取新消息?
该示例不一定是可扩展的、安全的或完整的,它只需要工作即可!
当前回答
这里是Erik Dubelboer使用Content类型:multipart/x-mixed-replace-header在PHP中的一个简单的长轮询示例:
<?
header('Content-type: multipart/x-mixed-replace; boundary=endofsection');
// Keep in mind that the empty line is important to separate the headers
// from the content.
echo 'Content-type: text/plain
After 5 seconds this will go away and a cat will appear...
--endofsection
';
flush(); // Don't forget to flush the content to the browser.
sleep(5);
echo 'Content-type: image/jpg
';
$stream = fopen('cat.jpg', 'rb');
fpassthru($stream);
fclose($stream);
echo '
--endofsection
';
下面是一个演示:
http://dubbelboer.com/multipart.php
其他回答
这是一个关于如何使用PHP&jQuery进行长时间轮询的5分钟精彩视频:http://screenr.com/SNH
代码与上面dbr的示例非常相似。
谢谢你的代码,dbr。只有long_poller.htm中的一个小错别字
1000 /* ..after 1 seconds */
我想应该是
"1000"); /* ..after 1 seconds */
让它发挥作用。
对于那些感兴趣的人,我尝试了Django的等效版本。开始一个新的Django项目,比如说长轮询:
django-admin.py startproject lp
调用消息服务器的应用程序msgsrv:
python manage.py startapp msgsrv
将以下行添加到settings.py以创建模板目录:
import os.path
PROJECT_DIR = os.path.dirname(__file__)
TEMPLATE_DIRS = (
os.path.join(PROJECT_DIR, 'templates'),
)
在urls.py中定义URL模式如下:
from django.views.generic.simple import direct_to_template
from lp.msgsrv.views import retmsg
urlpatterns = patterns('',
(r'^msgsrv\.php$', retmsg),
(r'^long_poller\.htm$', direct_to_template, {'template': 'long_poller.htm'}),
)
msgsrv/views.py应该如下所示:
from random import randint
from time import sleep
from django.http import HttpResponse, HttpResponseNotFound
def retmsg(request):
if randint(1,3) == 1:
return HttpResponseNotFound('<h1>Page not found</h1>')
else:
sleep(randint(2,10))
return HttpResponse('Hi! Have a random number: %s' % str(randint(1,10)))
最后,templates/long_poller.htm应与上面相同,并更正了拼写错误。希望这有帮助。
你可以试试icomet(https://github.com/ideawu/icomet),一个用libevent构建的C1000K C++comet服务器。icomet还提供了一个JavaScript库,使用起来非常简单
var comet = new iComet({
sign_url: 'http://' + app_host + '/sign?obj=' + obj,
sub_url: 'http://' + icomet_host + '/sub',
callback: function(msg){
// on server push
alert(msg.content);
}
});
icomet支持多种浏览器和操作系统,包括Safari(iOS、Mac)、IE(Windows)、Firefox、Chrome等。
下面是我在C#中用于长轮询的一些类。基本上有6个类(见下文)。
控制器:处理创建有效响应所需的操作(数据库操作等)处理器:管理与网页(自身)的异步通信IAsynchProcessor:实现此接口的服务进程实例服务:处理实现IAsynchProcessor的请求对象请求:包含响应(对象)的IAsynchProcessor包装响应:包含自定义对象或字段
我认为客户端看起来像一个普通的异步AJAX请求,但您希望它需要“很长时间”才能返回。
然后服务器看起来像这样。
while (!hasNewData())
usleep(50);
outputNewData();
因此,AJAX请求将发送到服务器,可能包括上次更新的时间戳,以便hasNewData()知道您已经获得了哪些数据。然后,服务器在循环中休眠,直到新数据可用。一直以来,您的AJAX请求仍然连接,只是挂在那里等待数据。最后,当新数据可用时,服务器将其提供给AJAX请求并关闭连接。