这是Long Polling(Comet编程)的正确方法吗

时间:2012-06-15 04:17:46

标签: php javascript ajax comet long-polling

首先,我要感谢所有优秀的人才对新程序员有所帮助。

我有一个关于长轮询的问题。我研究了一些关于 Comet Programming的长轮询技术的文章。这个方法对我来说似乎很难,因为它有时也需要在服务器端安装一些脚本。

现在我找到了一个关于长轮询的例子。它工作得很好,但我不确定它是否是正确的方法。示例脚本是关于类似聊天的应用程序。这个PHP脚本的工作原理如下:

  1. php脚本会持续检查data.txt文件,直到更改为止。
  2. 更改data.txt后,新文本将在网页上输出。
  3. 这是php脚本:

    <?php
    $filename  = dirname(__FILE__).'/data.txt';
    
    // store new message in the file
    $msg = isset($_GET['msg']) ? $_GET['msg'] : '';
    if ($msg != '')
    {
        file_put_contents($filename,$msg);
        die();
    }
    
    // infinite loop until the data file is not modified
    $lastmodif    = isset($_GET['timestamp']) ? $_GET['timestamp'] : 0;
    $currentmodif = filemtime($filename);
    while ($currentmodif <= $lastmodif) // check if the data file has been modified
    {
        usleep(500000); // sleep 500ms to unload the CPU
        clearstatcache();
        $currentmodif = filemtime($filename);
    }
    
    // return a json array
    $response = array();
    $response['msg']       = file_get_contents($filename);
    $response['timestamp'] = $currentmodif;
    echo json_encode($response);
    flush();
    ?>
    

    我没有提供网页代码来简化问题。网页只有一个div,它会在每次更改时显示data.txt的文本。

    我的问题的要点是:

    • 这种循环方法是适当的方法来长时间轮询服务器吗?
    • 此外,当服务器正在执行sleep();时,其他同步请求会发生什么?
    • 是否有由于长轮询的连续脚本而减少服务器负载的任何技术?
    • 如果启动此长轮询请求的客户端断开连接,我们如何知道并相应地停止该断开连接的客户端的脚本

    请指导我解决这个问题...谢谢

2 个答案:

答案 0 :(得分:5)

是的,这是个主意。您应该记住,此脚本不会结束,并且将为每个用户生成一个PHP实例。我正在使用带有v8cgi服务器端的longpoll逻辑。客户端启动XMLHttp请求(XHR)后,服务器开始检查新输入的间隔。我添加了一个计时器服务器端,每5分钟发送一次响应,之后客户端 - 如果没有断开连接 - 重新发送XHR并重复该过程。

因此,服务器端机制的每个实例最多运行时间不超过5分钟,因为如果客户端断开连接,服务器在5分钟后发送的响应不会跟随新的XHR。

过程如下:

  • 客户端发送XHR
  • server spawns定期检查更新
  • 如果必须发送某些更新:服务器发送响应
    • 客户端处理响应并重新启动XHR
    • 服务器生成进程并定期检查更新
  • 如果5分钟没有更新:
    • 服务器发送响应并退出衍生进程
    • 客户端进程(空)响应重启XHR
    • 服务器生成新进程并开始检查
  • 如果必须发送某些更新:服务器发送响应
  • [...]
  • 如果5分钟没有更新:
  • [...]
  • 直到客户端断开连接(=服务器响应后没有新的XHR)

答案 1 :(得分:1)

是的,这是一种简单易用的方法,它不是正确的方法,但不是最好的主意。因为它会受到影响并且会引起很多问题,因为用户会增加。

对于共享主机,这不是一个好主意,这个方法只有在用户数量不大且你有自己的服务器时才能正常工作。如果您在共享托管服务器中使用此方法,则可能会遇到使用的最大服务器资源会话锁定问题,并且http服务可能在一段时间内不可用。

或者你可以使用现有的api,用于聊天应用程序,或者有一个可以运行像node.js和类似服务器模块这样的脚本的专用服务器