PHP background Скрипт, блокирующий соединение для всего браузера - PullRequest
0 голосов
/ 14 октября 2011

У меня следующая проблема:

PHP-скрипт вызывается через Ajax. Сам скрипт закрывает соединение, используя следующие строки

ignore_user_abort(true);
header("Content-Length: 0");
header("Connection: close");
flush();

и затем начинает отправлять кучу писем в фоновом режиме, используя phpMailer (в цикле и с использованием sleep (1) после каждого письма - в будущем я хочу, чтобы это было случайное количество секунд после 5 отправленных писем). Используя FireBug, я вижу, что соединение со скриптом напрямую прерывается. Письма также отправляются.

Однако я не могу открыть ни одной страницы, пока скрипт работает в фоновом режиме - они продолжают загружаться до тех пор, пока фоновый скрипт явно не завершится. Странная вещь: сценарий, похоже, не блокирует весь сервер, так как ограничение подключения относится только к браузеру, который инициировал фоновый сценарий. Поэтому после запуска сценария, скажем, в FireFox, я все равно могу получить доступ к страницам на сервере в Chrome.

В чем может быть причина? Есть ли предел открытых MYSQLi-соединений для браузера (для сеанса, то есть ...) - я не смог ничего найти по этому поводу ... Или браузер (хотя FireBug говорит, что соединение было разорвано) тем не менее ждет за ответ сценария?

Как я мог решить это? Заранее спасибо за любую помощь.

1 Ответ

6 голосов
/ 14 октября 2011

PHP-скрипт не может закрыть клиентское <-> соединение с сервером, кроме как путем выхода.выполнение заголовка Connection: close тоже ничего не делает, как это делается для запросов client-> server, и в любом случае является действием по умолчанию, если только клиент специально не запрашивает Connection: keep-alive.

. "работает в других браузерах"поведение, которое вы видите, обычно связано с тем, что PHP блокирует файл сеанса, когда запрос активен.Разные браузеры не будут обмениваться файлами cookie, поэтому каждый браузер имеет свой собственный сеанс.Поэтому, хотя Firefox связан с этим фоновым запросом, сеанс, который использует Chrome, совершенно не затронут.

Если вы хотите продолжать использовать FF, пока он ожидает обработки этого почтового сценария, выполните командуsession_write_close() перед тем, как войти в петлю почтовой программы.Это закроет и разблокирует файл сеанса, и вы сможете продолжить использовать сайт на другой вкладке FF.

Если вы хотите, чтобы этот скрипт был действительно независим от браузера, тогда ему придется pcntl_fork сам в фоновом режиме.Этот разветвленный потомок может обрабатывать обработку, совершенно не привязанную к браузеру, и оригинальный сценарий может завершиться, что позволяет закрыть соединение.

...