key-value
(noSQL
) хранилище, но и хороший инструмент реализующий паттерн pub/sub (еще ссылка):
publisher
- издатель посылает сообщения в опредленный каналsubscriber
- подписчик подписывается на определенный канал/каналы и обрабатывает поступившие сообщенияRedis
не доступен наружуДля php
есть библиотека реализующая работу с Redis.
Для отправки сообщения в канал достаточно:
php$oRedis->publish('channel-name', 'text of message');
Для обработки сообщений из канала/каналов, необходимо подписаться и установить обработчик:
php$oRedis = new Redis(); $oRedis->connect(REDIS_IP, REDIS_PORT); $oRedis->auth(REDIS_PASSWORD); $oRedis->subscribe(['channel-name'], 'Handler');
В приведенном выше коде происходит подписка на один канал channel-name
с установкой обработчика Handler
:
phpfunction Handler($oRedis, $sChannel, $sMessage) { ... }
Обработчик принимат 3 параметра (применение венгеркой нотации ненавязчиво определяет сигнатуру прямо в имени, что делает дополнительное описание аргументов бессмысленным, но для тех кто не знаком с такой нотацией ...):
oRedis
- объект класса Redis
sChannel
- название каналаsMessage
- сообщение каналаphp$oRedis->subscribe(['channel-name1', 'channel-name2'], 'Handler'); function Handler($oRedis, $sChannel, $sMessage) { switch($sChannel) { case 'channel-name1': ... break; case 'channel-name2': ... break; default: break; } }
После вызова метода subscribe
скрипт зависнет в ожидании сообщений на канале. Но не на долго ...
Ожидание сообщений на канале в Redis
может прерваться в связи с обрывом связи ... точнее php
сам оборвет соединение:
plaintextFatal error: Uncaught RedisException: Connection timed out in /home/byurrer/redis-pubsub/pubsub.php:44 Stack trace: #0 /home/byurrer/redis-pubsub/pubsub.php(44): Redis->connect('127.0.0.1', 6379) #1 /home/byurrer/rredis-pubsub/pubsub.php(70): Subscribe() #2 {main} thrown in /home/byurrer/redis-pubsub/pubsub.php on line 44
60
секунд. Именно поэтому соединение с Redis
оборвется через 60
секунд.Чтобы этого не произошло необходимо изменить ее значение на -1
. Самый простой способ это добавить в самое начало php
скрипта:
phpini_set("default_socket_timeout", -1);
Обработку разрыва соединения можно обработать обернув метод subscribe
в блок try
/catch
:
phptry { $oRedis->subscribe(['channel-name1', 'channel-name2'], 'Handler'); } catch(Exception $e) { ... }
Но можно обернуть весь блок инициализации Redis
:
phptry { $oRedis = new Redis(); $oRedis->connect(REDIS_IP, REDIS_PORT); $oRedis->auth(REDIS_PASSWORD); } catch(Exception $e) { ... }
В catch
блок можно написать в лог либо попытаться восстановить соединение.
Но если скрипт все-таки упал (возможно внутренние ошибки в скрипте), или просто хочется сделать автозапуск скрипта с подпиской на канал, то можно сделать из php скрипта демона.