我可以找到很多关于长轮询如何工作的信息(例如,这个和这个),但没有简单的例子说明如何在代码中实现这一点。

我能找到的只有cometd,它依赖DojoJS框架和一个相当复杂的服务器系统。。

基本上,我将如何使用Apache来服务请求,以及我将如何编写一个简单的脚本(例如,用PHP)来“长轮询”服务器以获取新消息?

该示例不一定是可扩展的、安全的或完整的,它只需要工作即可!


当前回答

WS-I小组发布了一个名为“可靠的安全配置文件”的东西,它有一个GlassFish和.NET实现,显然可以很好地进行交互操作。

幸运的是,还有一个Javascript实现。

还有一个Silverlight实现使用HTTP双工。当推送发生时,可以将javascript连接到Silverlight对象以获取回调。

也有商业付费版本。

其他回答

WS-I小组发布了一个名为“可靠的安全配置文件”的东西,它有一个GlassFish和.NET实现,显然可以很好地进行交互操作。

幸运的是,还有一个Javascript实现。

还有一个Silverlight实现使用HTTP双工。当推送发生时,可以将javascript连接到Silverlight对象以获取回调。

也有商业付费版本。

这里是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

谢谢你的代码,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应与上面相同,并更正了拼写错误。希望这有帮助。

为什么不考虑web套接字而不是长轮询?它们非常高效且易于设置。然而,它们仅在现代浏览器中受支持。这里是一个快速参考。

看看这篇博文,里面有Python/Django/gevent中一个简单聊天应用程序的代码。