First of all i read many of the topics in stackoverflow about connection_aborted before making this topic but i didn't find the solution i wanted.
I want the below script to end properly when the connection has been terminated between the server and the client. Sometime works , sometimes not. I don't know why.
The sample code is the following:
<?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 );
}
?>
What do i need to do to make it more accurate?
Thank you
The meaning connection_aborted()
is, that the server knows, that the connection to the client has been lost. As it happens, this very often is not the case:
- Think of the client unplugging the network cable, walking out of WiFi coverage, driving into a underground carpark with his mobile: No packet that says, that the connection was terminated is ever communicated between the client and the server. This means, that the server will learn about the connection dropping only, when sending the reply is unsuccessfull - possibly long after your script has ended.
- Think of a busy server (network-busy): It is quite likely, that the connection.ending packet is received and processed at the webserver only after your script has gone on running for an appreciable time.
Long story short: It is a property of TCP, that loss of connection might ot might not be detected immediately.
TCP requires that ALL sent packets be acknowledged by the client and therefore the server should detect this as a send timeout at the very least...
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();
}