Сокеты PHP, постоянное подключение к серверу для получения событий от Asterisk AMI?

Я хочу написать PHP-скрипт, который будет действовать как мини-демон для получения данных из удаленного сокета. Удаленный сервер является сервером VoIP Asterisk, и я буду подключаться к интерфейсу управления Asterisk (AMI) в попытке получать уведомления о событиях AMI. Соединение будет осуществляться через постоянно активный туннель SSH (с использованием autossh), который до сих пор был достаточно стабильным для нашего использования.

Вот план...

  • Сценарий PHP, подключающийся к локальному порту туннеля SSH, который перенаправляет на удаленный порт на другом конце, используя fsockopen() или, скорее всего, pfsockopen()
  • PHP-скрипт будет запускаться из CLI, и я думаю, что у меня должен быть какой-то сценарий оболочки для задания cron, чтобы проверить, что PHP-скрипт не остановился по какой-либо причине.
  • Мне нужно, чтобы этот PHP-скрипт работал постоянно и постоянно подключался к сокету для получения данных всякий раз, когда он публикуется на другом конце.
  • Память и ЦП не проблема, так как у нас есть много ресурсов на нашем сервере интрасети (используется преступным образом), но в равной степени я не хочу, чтобы этот сценарий вышел из-под контроля.
  • Сценарий PHP, как мы надеемся, будет реагировать на случайные данные, появляющиеся на другом конце сокета, а иногда и на вставку или обновление данных в базе данных MySQL. Очевидно, что я буду открывать/закрывать соединение с MySQL, когда это необходимо, а не просто оставлять его зависшим.

Прежде всего, это ужасная идея, которая никогда не сработает?

Я понимаю, что PHP, вероятно, не лучший язык для такого небольшого демона, как этот, но я уже успешно работал с PHP в CLI, и это язык, с которым мне удобнее всего в эти дни.

Существуют ли какие-либо функции PHP, которые могут срабатывать, когда данные публикуются на другом конце сокета?
Или я просто зацикливаюсь, используя fread() вот так...

while (!feof($socket)) {
$output .= fread($socket, 8192);
}

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

О каких минусах/подводных камнях следует помнить, думая о постоянно работающем PHP-скрипте, подключенном к сокету?

Привет, Б


person batfastad    schedule 11.10.2011    source источник


Ответы (2)


  • вы должны знать о потреблении памяти при написании демона PHP. Если не осторожно unset()/free()d, ваш демон может потреблять все больше и больше памяти с течением времени.

  • как вы уже сказали, PHP не лучший язык для этого, но он точно сработает. Я уже делал этот "хак" несколько раз.

  • имейте в виду, что fread() на сокете TCP не будет блокировать. Поскольку каждая строка завершается CR/LF (\r\n), а два CR/LF отмечают конец события/команды AMI, вы можете читать до тех пор, пока не произойдет "\r\n\r\n", а затем обработать это событие, а затем снова начать чтение. я бы установил блокировку сокета и использовал fgets() вместо fread(). таким образом гораздо проще обнаружить конец события AMI - без необходимости делать магию/разбиение строк.

person Kaii    schedule 28.10.2011
comment
Это отлично. Теперь он работает, используя fgets с блокировкой сокета, и, похоже, работает так, как ожидалось. Я буду следить за сценарием в течение следующих 24 часов. - person batfastad; 01.11.2011
comment
Сделанный. Использование памяти из memory_get_peak_usage(TRUE) кажется равным 1,25 МБ, что определенно приемлемо, и большая часть этого, вероятно, просто накладные расходы PHP. - person batfastad; 11.11.2011
comment
По-прежнему приходилось выполнять множество сопоставлений шаблонов регулярных выражений, чтобы выполнять разные действия с разными событиями, но у меня есть некоторая логика, которая ограничивает запросы к БД, поскольку события AMI могут происходить очень часто, даже в системе с 15 пользователями. Ваше здоровье! - person batfastad; 11.11.2011

Взгляните на ZeroMQ, библиотеку асинхронных сообщений. http://en.wikipedia.org/wiki/ZeroMQ

Вот ссылка на привязки php:

http://www.zeromq.org/bindings%3aphp

person Vlad Balmos    schedule 28.10.2011
comment
Ого - даже не знал, что такое существует. Очень, очень круто!! Обязательно попробую использовать ZeroMQ для этого проекта. - person batfastad; 01.11.2011