MixPHP V2.1 ecology: Swoole coroutine Redis subscriber

In OpenMix family bucket has a central Mix Redis Subscribe projects, which is not dependent on a phpredis extension, directly resolve Redis protocol dedicated to the treatment of a subscription library, any Swoole framework can be used, it can be widely used in WebSocket development, in MixPHP skeleton also contains the default library.

Why Development

MixPHP after V2.1 completion of the development, I am trying to develop a mechanism WebScoket subscription-based service that requires a subscription can dynamically switch channels, but phpredis subscription methods can not achieve the following functions:

$redis = new \Redis();
$res   = $redis->pconnect('127.0.0.1', 6379, 0);
$redis->subscribe(['test'], function ($instance, $channelName, $message) {
    echo $channelName, "==>", $message, PHP_EOL;
});


  • Subscribe to succeed not know

When the above code, when executed subscribe to block the execution, only when the news came to the anonymous function will be performed, and does not subscribe to the successful implementation of the closure at that time, but redis-cli executed subscription, redis-server there is a reply message subscription is successful, therefore the design problem phpredis.

  • Can not dynamically increase channel subscribe

Due to subscribe blocking the execution, the code can only be executed in the callback when there is news to trigger a callback, thus increasing the dynamic channel is inoperable.

  • unsubscribe only be performed in the callback

Because that blocking callbacks design of the above, if you need to cancel a channel, this can only be operated when the news came, but the actual demand is usually required channel can be canceled at any time.

  • Unable to close the connection in other coroutine

When you try to phpredis outside the anonymous function other coroutine in close connection will throw an exception PHP Fatal error: Uncaught RedisException: read error on connection, which makes a closed subscription in redis connections are not elegant implementation.

Create the wheel

When I learned that redis protocol is a simple text protocol, I decided to abandon the subscription library phpredis made himself a nice, new wheel has the following advantages:

  • Do not rely phpredis extension
  • Smoothing Review: can be added at any time, unsubscribe channel needs to achieve seamless switching channels.
  • Cross coroutine safely shut down: turn off the subscription at any time.
  • Get Message Channel: The reference library package style language golang go-redis library package, subscription message acquired by the channel.
$sub = new \Mix\Redis\Subscribe\Subscriber([ // 连接失败将抛出异常
    'host'     => '192.168.198.1',
    'port'     => 6379,
    'timeout'  => 5,
    'password' => '',
]);
$sub->subscribe('foo', 'bar'); // 订阅失败将抛出异常

$chan = $sub->channel();
while (true) {
    $data = $chan->pop();
    if (empty($data)) { // 手动close与redis异常断开都会导致返回false
        if (!$sub->closed) {
            // redis异常断开处理
            var_dump('Redis connection is disconnected abnormally');
        }
        break;
    }
    var_dump($data);
}


Receiving the subscription message:

object(Mix\Redis\Subscribe\Message)#8 (2) {
  ["channel"]=>
  string(2) "foo"
  ["payload"]=>
  string(4) "test"
}


Guess you like

Origin www.oschina.net/news/112703/mixphp-2-1-released