使用PHP会话进行AJAX长轮询

时间:2016-01-10 05:55:19

标签: php jquery ajax session

我有以下内容:

SCRIPT:

function poll(){
    $.ajax({
        ...
        url: poll.php,
        success: function(res){
            $('#count').html(res);
            poll();
        }
    });
}
poll();

poll.php:

session_start();
$count = $_SESSION['count'];
session_write_close();
while(true){
    $newcount = $_SESSION['count'];
    if($newcount != $count){
        $count = $newcount;
        break;
    }
    sleep(1);
}
echo $count;

在我的php中,当$_SESSION['count']被更改时,它会突破while loop,然后更新DOM元素'#count,然后再次轮询更改。但我的问题是,当我尝试从另一个实例更改$_SESSION['count']时,运行poll的实例会一直等待请求完成。这意味着即使我从另一个实例更改poll.php,我的while loop也不会突破$_SESSION['count']

这里有什么问题?

1 个答案:

答案 0 :(得分:2)

session_write_close()之后,会话结束。这意味着进一步的变化不会反映在$_SESSION

您需要重新打开会话才能阅读:

session_start();
$count = $_SESSION['count'];
session_write_close();
while(true){
    session_start();
    $newcount = $_SESSION['count'];
    session_write_close();

    if($newcount != $count){
        $count = $newcount;
        break;
    }
    sleep(1);
}
echo $count;

但请注意,在您的网络服务器上运行这样的无限循环通常不是一个好主意。您可以轻松地让自己接受拒绝服务攻击:在无限循环中运行的每个php会话消耗内存并与Web服务器建立开放连接,因此您可以非常快速地结束您的Web服务器无法响应要求,因为它的所有工人都被束缚在一个无限循环中。

如果您确实需要在PHP中执行此操作,我强烈建议工作人员在一段时间后自动退出。更好的方法是使用专门用于长轮询的其他技术(例如,node.js WebSockets服务器)。