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

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

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

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


当前回答

Tornado是为长轮询而设计的,它在/examples/chatdemo中包含了一个非常小的(数百行Python)聊天应用程序,包括服务器代码和JS客户端代码。它的工作原理如下:

客户机使用JS请求更新,因为(最后一条消息的数量),服务器URLHandler接收这些消息并添加回调以响应客户机到队列。当服务器收到新消息时,onmessage事件将触发,循环通过回调,并发送消息。客户端JS接收消息,将其添加到页面,然后请求更新此新消息ID。

其他回答

下面是我为Inform8 Web开发的一个长轮询解决方案。基本上,重写类并实现loadData方法。当loadData返回值或操作超时时,它将打印结果并返回。

如果脚本的处理时间可能超过30秒,则可能需要将set_time_limit()调用更改为更长的时间。

Apache 2.0许可证。github上的最新版本https://github.com/ryanhend/Inform8/blob/master/Inform8-web/src/config/lib/Inform8/longpoll/LongPoller.php

Ryan

abstract class LongPoller {

  protected $sleepTime = 5;
  protected $timeoutTime = 30;

  function __construct() {
  }


  function setTimeout($timeout) {
    $this->timeoutTime = $timeout;
  }

  function setSleep($sleep) {
    $this->sleepTime = $sleepTime;
  }


  public function run() {
    $data = NULL;
    $timeout = 0;

    set_time_limit($this->timeoutTime + $this->sleepTime + 15);

    //Query database for data
    while($data == NULL && $timeout < $this->timeoutTime) {
      $data = $this->loadData();
      if($data == NULL){

        //No new orders, flush to notify php still alive
        flush();

        //Wait for new Messages
        sleep($this->sleepTime);
        $timeout += $this->sleepTime;
      }else{
        echo $data;
        flush();
      }
    }

  }


  protected abstract function loadData();

}

Tornado是为长轮询而设计的,它在/examples/chatdemo中包含了一个非常小的(数百行Python)聊天应用程序,包括服务器代码和JS客户端代码。它的工作原理如下:

客户机使用JS请求更新,因为(最后一条消息的数量),服务器URLHandler接收这些消息并添加回调以响应客户机到队列。当服务器收到新消息时,onmessage事件将触发,循环通过回调,并发送消息。客户端JS接收消息,将其添加到页面,然后请求更新此新消息ID。

对于ASP.NET MVC实现,请查看NuGet上提供的SignalR。。请注意,NuGet与Git源代码相比常常是过时的,因为Git源经常提交。

在Scott Hanselman的博客上阅读有关SignalR的更多信息

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

我用这个来掌握Comet,我还使用Java Glassfish服务器设置了Comet,并通过订阅cometdaily.com找到了许多其他示例