M
M
marliotto2015-10-03 11:13:34
PHP
marliotto, 2015-10-03 11:13:34

Why doesn't php-fpm stop when connection is cancelled?

Check with the following script

<?php

ignore_user_abort(false);

echo 'message';

sleep(8);

while(ob_get_level()) {
ob_end_flush();
}

$status = connection_status();

if ($aborted = connection_aborted()) {
    file_put_contents(__DIR__ . '/a', date('d.m.Y H:i:s') . ' - aborted (' . $aborted . '); Status - ' . $status);
    echo 'aborted';
} else {
    file_put_contents(__DIR__ . '/a', date('d.m.Y H:i:s') . ' - connected (' . $aborted . '); Status - ' . $status);
    echo 'connected';
}

The script is always processed completely and connection_aborted() === 0.
I tried to play with nginx with the fastcgi_ignore_client_abort option.
If the value is off, 499 error gets into the nginx log, but the script is still executed to the end and connection_aborted() === 0.
How to make php know if the client fell off or not?
nginx version 1.6.2
php version PHP/5.4.45
UPD: The problem is not with the request, it is fast.
The problem is slow clients with poor internet connection.
I need to know that they refused to wait for an answer.

Answer the question

In order to leave comments, you need to log in

3 answer(s)
M
marliotto, 2015-10-04
@marliotto

It only worked with a socket connection.
PHP also learns about a connection failure only after sending data to the client (via echo, header) and flushing the buffer.
The code will be as follows

<?php

//Работает только при socket соединении
//необходимо выставить в true. Иначе после вывода данных выполнение скрипта прервется
ignore_user_abort(true);

sleep(8);

echo 'message';
flush();//только теперь php знает, оборвалось соединение или нет

$status = connection_status();

if ($aborted = connection_aborted()) {
    file_put_contents(__DIR__ . '/a', date('d.m.Y H:i:s') . ' - aborted (' . $aborted . '); Status - ' . $status);
    echo 'aborted';
} else {
    file_put_contents(__DIR__ . '/a', date('d.m.Y H:i:s') . ' - connected (' . $aborted . '); Status - ' . $status);
    echo 'connected';
}

Related links
stackoverflow.com/a/25251852
php.net/manual/ru/function.ignore-user-abort.php (see note)

O
OnYourLips, 2015-10-03
@OnYourLips

All lengthy operations must be performed outside the web interface.
From the web interface, you only need to add tasks for such commands/servers.

P
Puma Thailand, 2015-10-03
@opium

your way to nowhere give up this shit code and do everything right, not a crutch on a crutch.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question