Принудительное заверение ожидание Apache и отдача страницы до завершения работы скрипта

Статус
В этой теме нельзя размещать новые ответы.

Горбушка

Ищу её...
Регистрация
2 Май 2008
Сообщения
3.444
Реакции
2.523
Всем привет.

Имеется скрипт, который до определённого момента готовит пользовательский контент, затем отдаёт пользователю (читать Apache) готовую страницу. Затем происходит расчёт статистики, обновление счётчиков и прочая фигня, которую пользователю дожидаться не обязательно.

Вопрос - можно ли после отдачи контента Apache'у "сказать" ему, чтобы больше не ждал, но при этом PHP продолжил бы работать и досчитывать показатели в БД?

Условно:

PHP:
<?php

echo "test";

// Тут прекращаем ожидать контент от PHP

while ( $i < 1 000 000) {...}

file_put_content(...);

?>

Вот чтобы пользователь получил свой "test" сразу, а после отработки 1 000 000 раз цикла произошла запись в файл, но пользователь этого уже не ждал...

Ещё раз для танкистов, после момента отдачи контента больше пользователю ничего отправляться не будет, сессию можно разрывать, процесс Apache останавливать и т.д. Будет идти только запись в БД и файлы, пользователю даже "Ок" отправляться не будет...

Надеюсь понятно объяснил.
 

KillDead

Хранитель порядка
Регистрация
11 Авг 2006
Сообщения
894
Реакции
579
Задавался таким же вопросом, но решения не нашёл. Всё сводилось к тому что мы отправляем заголовок что закончили и надеемся что сработает, а это получается далеко не всегда. Ну, есть и немного другие решения - через курл или сокеты но вроде это не по тз, мне не подходило.
 

dandandan

Мой дом здесь!
Регистрация
7 Авг 2008
Сообщения
1.036
Реакции
292
PHP:
<?php
// buffer all upcoming output
ob_start();
echo "Here's my awesome web page";
// get the size of the output
$size = ob_get_length();
// send headers to tell the browser to close the connection
header("Content-Length: $size");
header('Connection: close');
// flush all output
ob_end_flush();
ob_flush();
flush();
// close current session
if (session_id()) session_write_close();
/******** background process starts here ********/
Вот решение.
За отключение браузера от сервера отвечает header('Connection: close');
Тут несколько примеров... Для просмотра ссылки Войди или Зарегистрируйся
и
Для просмотра ссылки Войди или Зарегистрируйся
 

Горбушка

Ищу её...
Регистрация
2 Май 2008
Сообщения
3.444
Реакции
2.523
Тут 2 варианта поведения браузера:
1) Он отключается и отдаёт заголовок (точно не знаю механизм взаимодействия) о разрыве сессии. Apache принимает его и киляет процесс php, т.к. ответ больше никто не ждёт.
2) Браузер не разрывает сессию и благополучно ждёт пока её разорвёт Apache... И в итоге человек висит и ждёт не пойми чего, а страница ещё не рендерится даже...

В общем, на браузеры тут полагаться нельзя. В результате был выбран сценарий следующий:
1) Мы передаём браузеру заголовок с размером пакета и контент
2) Разрываем сессию между Apache и nginx, тем самым браузер получает сигнал о прекращении сессии
3) Сама сессия Apache - PHP продолжает висеть до окончания отработки скрипта, но результат браузеру не передаётся.

Как-то так...
Код описан в посте @dandandan + делается настройка сервера чтобы Apache не рвал сессию с PHP.
 

pastuhoff

Постоялец
Регистрация
11 Июл 2012
Сообщения
59
Реакции
8
1) Он отключается и отдаёт заголовок (точно не знаю механизм взаимодействия) о разрыве сессии. Apache принимает его и киляет процесс php, т.к. ответ больше никто не ждёт.
Если php-скрипт запускается через javascript`овый XMLHttpRequest() - убийство этого php-скрипта все-равно возможно (при закрытии браузера или еще при каких-либо обстоятельствах)?
 
Последнее редактирование:

SexKiller

Профессор
Регистрация
20 Апр 2006
Сообщения
211
Реакции
44
В общем, на браузеры тут полагаться нельзя. В результате был выбран сценарий следующий:
1) Мы передаём браузеру заголовок с размером пакета и контент
2) Разрываем сессию между Apache и nginx, тем самым браузер получает сигнал о прекращении сессии
3) Сама сессия Apache - PHP продолжает висеть до окончания отработки скрипта, но результат браузеру не передаётся.
+
Код:
register_shutdown_function(function(){
    sleep(15);
    file_put_contents('test.txt', 'Проверка записи после завершения скрипта');
});
Просто находка, спасибо.
 
Статус
В этой теме нельзя размещать новые ответы.
Сверху