[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Отдача контента и обрыв соединения средствами PHP
teimos
Вот такая интересная задача:

1. Есть php скрипт на сервере, обрабатывающий большое количество данных и работающий продолжительное время (несколько часов как минимум).
2. Есть клиентское приложение с кнопкой "Старт" (html страничка + jQuery)

При нажатии на "старт" происходит аякс-запрос к скрипту. Нужно скриптом получить запрос, отдать какой-либо ответ (например в json) и оборвать соединение, но продолжить работать в фоне (типа ignore_user_abort). Как это можно сделать? Именно интересует что-то вроде:

<?php
echo json_encode($data);
abort_connection();
//дальше скрипт продолжает свою работу, но клиент уже получил информацию, что мол проект успешно запущен.
?>



Спустя 2 минуты, 59 секунд (26.09.2011 - 06:10) kirik написал(а):
Можно запустить другой скрипт в фоне или воспользоваться pcntl

Спустя 24 минуты, 37 секунд (26.09.2011 - 06:35) teimos написал(а):
Хм... а если нет возможности поставить pcntl?

А насчет запуска в фоне через exec и system - тоже не то пальто, могут быть ведь разные операционные системы, с разными путями до интерпретатора, не говоря уже о том, что скрипт пользователь может запускать локально на денвере или аналогичном эмуляторе сервера.

UPD. Неужели нет стандартного способа?
Либо как-то так сделать, типа аякс посылает запрос серверу, сервер обратно отдает какие-либо данные и уже аяксом обрывать соединение. Я просто недостаточно разбираюсь во внутренних процессах... jQuery ведь будет ждать пока открыто соединение...

Спустя 3 минуты, 26 секунд (26.09.2011 - 06:39) kirik написал(а):
teimos
Тогда по-нормальному никак.
Можно делать запрос через curl к другому скрипту, и выставить таймаут в секунду. Но это ужасный костыль и я очень не рекомендовал бы его использовать. Просто как временный выход из положения.

Спустя 6 минут, 18 секунд (26.09.2011 - 06:45) teimos написал(а):
Цитата (kirik @ 26.09.2011 - 03:39)
Можно делать запрос через curl к другому скрипту, и выставить таймаут в секунду

А это естественно костыль, и он не подходит по ряду причин.

Спустя 13 минут, 28 секунд (26.09.2011 - 06:58) kirik написал(а):
teimos
Тогда выбирайте меньшее из зол wink.gif

Спустя 1 час, 6 минут, 31 секунда (26.09.2011 - 08:05) linker написал(а):
Ёпт, HTTP-соединение уже по своей сути является тем, что тебе надо: Запрос-Ответ-Разрыв соединения. Нет постоянных соединений вообще, об чём речь. В любом случае без posix-функций для межпроцессорного взаимодействия тебе не обойтись. Либо через сокеты.

Спустя 43 минуты, 14 секунд (26.09.2011 - 08:48) teimos написал(а):
Цитата (linker @ 26.09.2011 - 05:05)
Нет постоянных соединений вообще, об чём речь.

Я имею ввиду, что php-скрипт разрывает соединение только в конце своей работы (исключая всякие exit и die конечно же), а он у меня работате непрерывно несколько часов.

Цитата (linker @ 26.09.2011 - 05:05)
В любом случае без posix-функций для межпроцессорного взаимодействия тебе не обойтись

Можно поподробнее? В какую сторону копать?

Сокеты так же как и курл не подходят.

Спустя 7 минут, 31 секунда (26.09.2011 - 08:56) linker написал(а):
1. PHP не имеет многопоточности, а следовательно выполняя какую-то работу скрипт не сможет параллельно откликнуться на какое-либо событие из вне, не прервав своей основной работы.
2. Запрос идёт, насколько я понимаю через HTTP, а значит работает протокол: запрос-ответ-конец работы с разрывом соединения.
3. Твой скрипт на сервер должен быть сам сервером.
4. Твой скрипт открывает кладёт данные в queue или shared memory, клиентская сторона делает запрос на сервер ко второму скрипту, который забирает данные из queue или shared memory и отдаёт клиенту с завершением своей работы.

Спустя 17 минут, 13 секунд (26.09.2011 - 09:13) teimos написал(а):
Пока что вижу только один выход из ситуации без дополнительных костылей:

1. Делать запрос к серверу, который запускает скрипт
2. Обрывать на клиентской стороне соединение через 3-5 секунд
3. Подождать еще секунд 10
4. Сделать повторный запрос (скрипт на сервере вернет ошибку типа "проект уже запущен" и прекратит работу, в противном случае опять пойдет п.2)

Спустя 13 минут, 19 секунд (26.09.2011 - 09:26) linker написал(а):
При каждом HTTP-запросе, создаётся новый php-процесс, твой первый запущенный так и останется без дела, а ты засрёшь память сервака.

Спустя 22 минуты, 11 секунд (26.09.2011 - 09:48) teimos написал(а):
Так первый php-процесс будет долго работать (в нем директива ignore_user_abort(true)wink.gif.
А второй, при повторном обращении, увидит что уже запущена копия, и завершит свою работу сразу же.

Спустя 10 минут, 4 секунды (26.09.2011 - 09:58) linker написал(а):
А чем ты во втором собираешься понимать, что первый уже запущен? Вопрос конечно глупый и решение очевидное, но всё же.

Спустя 9 минут, 43 секунды (26.09.2011 - 10:08) teimos написал(а):
Старым проверенным способом =)
При старте проекта, он в БД ставит статус проекту "генерация", а по окончанию работы "ожидание".
Вот вторая копия скрипта и будет сверяться со статусом из базы.

Можно конечно через командную строку юниксовскую выдирать айдишник запущенного процесса, но уж больно разные условия использования могут быть у скрипта, в том числе запрет exec и system.

Спустя 11 минут, 11 секунд (26.09.2011 - 10:19) linker написал(а):
Ну получил статус "ожидание", дальше что?

Спустя 15 часов, 6 минут, 33 секунды (27.09.2011 - 01:26) teimos написал(а):
Ммм... ну типа того:

$status = $this->check_status();
if ($status == 1) exit(json_encode(array('error'=>'Проект уже запущен!')));
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.