2014-05-08 44 views
0

首先,我在阅读关于connection_aborted的关于stackoverflow的许多主题之后,发表了这个主题,但是我没有找到我想要的解决方案。PHP connection_aborted()并不总是有效

我想让下面的脚本在服务器和客户端之间的连接终止时正常结束。有时可以工作,有时不可以。我不知道为什么。

示例代码如下:

<?php 

ignore_user_abort(true); 
register_shutdown_function('shutdown'); 


$url = "http://127.0.0.1:8000"; 
$file_handler = @fopen($url, "rb") or die("Open failed"); 

foreach ($http_response_header as $h) 
{ 
    header($h); 
} 

$bytes = 0; 
while (! feof($file_handler) and ! connection_aborted()) 
{ 
    $response = stream_get_line($file_handler, 4096); 
    $bytes += strlen($response); 
    echo $response; 
} 

fclose($file_handler); 


function shutdown() 
{ 
    global $file_handler; 

    if (! is_null($file_handler)) 
    { 
     fclose($file_handler); 
     //do some other code 
    } 

    posix_kill(getmypid(), 9); 
} 

?> 

什么我需要做,使之更加准确呢?

谢谢

回答

0

意义connection_aborted()是,服务器知道,即到客户端的连接已丢失。碰巧,情况并非如此:

  • 想想客户端拔掉网线,走出WiFi覆盖范围,用他的手机驶入地下停车场:没有数据包说,连接终止了在客户端和服务器之间的通信。这意味着服务器只会在连接丢失的情况下才能知道,当发送答复不成功时 - 可能在脚本结束后很长时间。
  • 想象一下繁忙的服务器(网络繁忙):只有在脚本运行了相当长的时间后,才有可能在web服务器上接收和处理connection.ending数据包。

长话短说:它是TCP的一个属性,可能不会立即检测到连接丢失。

+0

是的,我明白,它不能检测到它正好在用户断开连接的时间,但在用户成功断开连接的情况下,永远不会关闭! php脚本PID仍然保持打开状态,关闭它的唯一方法是手动终止它。 我不知道为什么会发生这种情况。缓冲区有问题吗?我需要使用同花顺还是其他?我想我尝试了他们,但他们没有工作。 – user3393046

+0

做一些事情,需要在脚本提前结束时取消,并依靠'connection_aborted()'将无法可靠地工作。没有任何冲洗,也没有其他技巧会改变TCP工作原理的现实。 –

0

TCP要求所有发送的数据包由客户端进行确认,因此服务器应检测为至少是一个发送超时...

session_write_close();//to make flush work 
while (connection_status() !== 0) {//this will work if the connection is properly shutdown 
            //or if it is simply disconnected... 
    sleep(1); 
    echo "whatever"; 
    ob_flush(); 
    flush(); 
} 
相关问题