替代PHP函数connection_aborted()?

时间:2014-02-16 20:09:25

标签: php websocket

我已经花了两天多时间解决这个问题。它看起来PHP函数connection_aborted()不能可靠地工作。有时它会报告与客户端的中断连接,但是大约50%它没有报告中止。

还有其他方法可以从PHP脚本中检测与客户端的中止连接吗?也许建立套接字连接或其他什么?

示例代码:

这是我最新版本的文件下载代码。下载甚至可以在大文件上正常工作,但connection_aborted()只能偶尔使用。

// disable script abort
ignore_user_abort(true);

// never expire this download script
set_time_limit(0);

 while(!feof($fileObject) && (connection_status()==0))
        {
            //usleep(100000);

            print(@fread($fileObject, $chunkSize));

            // gradually output buffer to avoid memory problems by downloading large files
            ob_flush();
            flush();

            $nLoopCounter++;
            $transferred += $chunkSize;
            $downloadPercentage = (($nLoopCounter * $chunkSize) / $fileSize) * 100;

            $result = mysqli_query($dbc, "UPDATE current_downloads SET progress_percent=$downloadPercentage, transferred=$transferred, connection_aborted=$strConnectionAborted, iteration=$nLoopCounter WHERE user_id=1;");
            if($result == false)
            {
                // close the database connection
                mysqli_close($dbc);

                // close the file
                fclose($handle);

                // prepare output message
                exit(json_encode(array("result" => false, "error" => "Error Processing Database Query.")));
            }
        }

        // check if the client was disconnected
        // important for cancelled or interrupted downloads
        if ( (connection_status()!=0) || (connection_aborted()!=0) )
        {
            // empty the output buffer
            ob_flush();
            flush();

            ChromePhp::log("Connection Aborted");

            // sent to the database that the connection has been aborted
            $result = mysqli_query($dbc, "UPDATE current_downloads SET connection_aborted=TRUE WHERE user_id=1;");

            // close the database connection
            mysqli_close($dbc);

            // close the open file
            @fclose($fileObject);

            exit(json_encode(array("result" => false, "error" => "Connection with the client was aborted.")));
        }

谢谢你,亲切的问候。

1 个答案:

答案 0 :(得分:0)

使用默认设置,如果浏览器关闭连接,PHP将中止正在运行的脚本。您可以使用函数ignore_user_abort()或ini设置ignore_user_abort更改此默认行为。

为了使用函数connection_aborted(),您需要先执行其中一个步骤,否则将永远不会达到connection_aborted()。以下是ignore_user_abort()的示例:

ignore_user_abort(TRUE);
for($i = 0; $i < 10; $i++) {
    sleep(1);
    // click the stop button in your browser ...
    if(connection_aborted()) {
        // we can't use echo anymore as the connection to the
        // browser was closed. that's why we write to test file
        file_put_contents('/tmp/test.file', 'The connection was aborted');
    }
}

但这不是全部。如果使用register_shutdown_function()注册关闭函数,即使脚本因为缺少ignore_user_abort()而被告知终止,也会调用此函数。以下示例显示了这一点:

register_shutdown_function(function() {
    // click the stop button in your browser ...
    if(connection_aborted()) {
        // we can't use echo anymore as the connection to the
        // browser was closed. that's why we write to test file
        file_put_contents('/tmp/test.file', 'The connection was aborted');
    }
});

您可以在文档中关注本文:http://www.php.net/manual/en/features.connection-handling.php。它解释了PHP的连接处理。