PHP, приостановить выполнение скрипта, пока событие не будет сигнализировано другим запущенным скриптом? - PullRequest
0 голосов
/ 04 февраля 2011

Я хочу, чтобы один скрипт PHP ожидал события, отправленного во время выполнения другого скрипта.

Пользователь A и пользователь B оба являются посетителями моего сайта. Когда пользователь A посещает index.php, страница начинает выполнение, но не возвращается, пока пользователь B также не посетит index.php. (Страница отображается только тогда, когда оба пользователя подключены к веб-серверу, например, как два охранника, открывающих сейф, поворачивая ключ одновременно.)

Один из способов сделать это состоит в том, чтобы index.php приостановил свое выполнение до получения уведомления, вызванного посещением index.php другим пользователем.

Для этого я посмотрел на

  1. Libevent; Но, похоже, он не позволяет отправлять «ID» или «строки» во время сигнализации.
  2. Event_Dispatcher от груши; Но это не работает "между" сценариями.
  3. Функции разделяемой памяти PHP; Но, похоже, не может ждать, пока память не изменится.

Ответы [ 4 ]

3 голосов
/ 04 февраля 2011

Возможно, вы не захотите, чтобы PHP-скрипт полностью останавливался. Пользователь просто сидит и думает, что страница застыла. Вместо этого я бы использовал AJAX для сохранения состояния USER-A в базе данных, а затем использовал AJAX, чтобы снова проверить, сохранено ли также состояние USER-B. Идея состоит в том, чтобы AJAX молча проверял статус USER-B в фоновом режиме. Когда он обнаружит логин, пусть ваша функция обратного вызова сделает что-то на странице!

1 голос
/ 15 июня 2016

В коде для вашего «ожидающего» запроса (Пользователь A) создайте новый прослушивающий сокет (http://php.net/manual/en/sockets.examples.php), связанный с адресом и портом localhost, который не будет конфликтовать ни с чем другим (например, 127.12). 34.56 (порт 7890), затем дождитесь соединения, вызвав socket_accept. Если в этом состоянии уже есть запрос, он завершится ошибкой, иначе он будет ожидать соединения.

В вашем запросе «сигнализация» (пользователь B) создайте новый сокет и подключитесь к вашему прослушивающему сокету. Обработчик PHP, ожидающий запрос пользователя A, немедленно вернется из вызова socket_accept, в котором он был заблокирован, и вы можете продолжить. Если вам нужно передать какие-либо сообщения между ними, вы можете просто читать и записывать сообщения в и из сокетов.

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

- не создает ненужных HTTP-запросов, запросов к БД или циклов ЦП, которые потребляют ресурсы и сетевой трафик

-Действует немедленно, когда событие запуска происходит без задержки

-Это не зависит от БД или файла

Основным недостатком является то, что ваш PHP должен иметь разрешения для открытия сокетов и подключения к ним, что часто не имеет места в средах общего хостинга.

Например, см. https://gist.github.com/root9b/e1f0b82769296b06c079e53c7362bb94

1 голос
/ 04 февраля 2011

Как насчет использования sleep и db?

Клиент 1 входит в систему, PHP вставляет «ожидающую запись», а затем опрашивает базу данных через заданный интервал (возможно, используя time_nanosleep) для чего-то, что пометило его »полный».Клиент 2 входит в систему, PHP обновляет «ожидающую запись», чтобы установить ее как «завершенную».Клиент 1, видя, что процесс завершен, идет своим путем.

Если у вас нет базы данных, это можно сделать с помощью простого временного файла.

0 голосов
/ 04 февраля 2011

вы ищете демона, есть некоторая информация, как его создать:

http://kevin.vanzonneveld.net/techblog/article/create_daemons_in_php/

...