php implements redis message publishing subscription

Basic Introduction

Pub/Sub function (means Publish, Subscribe) is the publishing and subscription function

  • In event-based systems, Pub/Sub is a widely used communication model, which uses events as the basic communication mechanism to provide loosely coupled interaction modes required by large-scale systems: subscribers (such as clients) express an event or a type of event they are interested in receiving in the form of event subscriptions; publishers (such asSuch as servers) Subscribers can be notified of events of interest to them at any time.
  • The message publisher, the publish client, does not need exclusive links. You can use the same redis-client link to do other things (for example, INCR, etc.) while publishing the message.
  • Message subscribers, the subscribe client, need exclusive links, that is, redis-client s cannot interpolate other operations during subscribe, and clients are blocked waiting for messages from the "publish side"; this is understandable, so the subscribe side needs to use separate links and even need to be in additional threadsUse.

When using bank card to consume, banks often inform users of this transaction through WeChat, SMS or email, which is a publishing subscription mode. Publishing here is the publication of transaction information, while subscription is a variety of channels.This is common in practice, and Redis supports such a pattern.

Publishing a subscription mode first requires a message source, that is, a message to be published, such as a bank notification in the example.The first is the bank's accounting system, which receives orders for transactions and sends messages after successful accounting. At this time, subscribers can receive this message for processing, and the observer mode is a typical application of this mode.

Terminal implementation

Subscribe to channel'chat'

Publish a message

code implementation

subscribe.php

<?php
ini_set('default_socket_timeout', -1);  //php configuration settings do not timeout
$redis = new Redis();
$redis->connect("127.0.0.1",6379);
//$redis->setOption (Redis:: OPT_READ_TIMEOUT, -1); //redis mode setting does not timeout, recommended

$redis->subscribe(['chan'],'callback');     //Callback is the callback function name
//$redis->subscribe (['chan'], array (new TestCall (),'callback'); //If the callback function is the method name in the class, write this

// Callback function, where processing logic is written
function callback($instance, $channelName, $message)
{
         echo $channelName, "==>", $message, PHP_EOL;
         
         //$instance, the redis instance object created above, is the default parameter in the callback function, so no special arguments are required.Commands other than SUBSCRIBE, PSUBSCRIBE, UNSUBSCRIBE, PUNSUBSCRIBE cannot be used here
         //If you want to use other commands in redis, do this
         $newredis = new Redis();
        $newredis->connect("127.0.0.1", 6379);
        echo $newredis->get('test') . PHP_EOL;
        $newredis->close();
        
          //You can handle different business logic based on $channelName, $message
          switch($chan) {
               case 'chan-1':
                  ...
                  break;
         
               case 'chan-2':
                              ...
                   break;
           }
           
           switch($message) {
               case 'msg1':
                  ...
                  break;
         
               case 'msg2':
                              ...
                   break;
           }
    
}

publish.php

<?php

$redis = new Redis();
$redis->connect("127.0.0.1",6379);

$redis->publish('chan','this is a message');

Code introduction

  1. Set no timeout in subscribe.php

Method 1:ini_set('default_socket_timeout', -1);

Method 2: $redis->setOption (Redis:: OPT_READ_TIMEOUT, -1);

If no timeout is set, an error will be reported after 60s

PHP Fatal error:  Uncaught RedisException: read error on connection to 127.0.0.1:6379 in subscribe.php:6

Method 1 is implemented by temporarily modifying the configuration value of ini, default_socket_timeout defaults to 60s, default_socket_timeout is the timeout parameter of socket stream, that is, the entire process of socket stream from establishment to transmission to closure must be completed within the time set by this parameter. If it cannot be completed, PHP will automatically terminateBundle this socket and return a warning.

Mode 2 modifies the redis configuration item so that it only works on redis connections and will not have an unexpected impact on other methods as opposed to mode 1.

Bulk Subscription

psubscribe for redis supports batch subscription through pattern matching

$redis->psubscribe (['my*'],'psubscribe'); //Callback function writes function name
perhaps
$redis->psubscribe (['my*'], array (new TestCall (),'psubscribe'); //callback functions are methods in classes whose names write your own defined classes

subscribe.php

<?php
//ini_set('default_socket_timeout', -1); //No timeout
$redis = new Redis();
$redis->connect("127.0.0.1",6379);
$redis->setOption(Redis::OPT_READ_TIMEOUT, -1);

//Match mode 1: Publish available $redis->publish ('mymest','This is a message');
//$redis->psubscribe(['my*'],'psubscribe');    

//Match Mode 2: Publish available $redis->publish ('mydest','This is a message');
//$redis->psubscribe(['my?est'],'psubscribe');

//Match mode 3: Publish can be $redis->publish ('myaest','This is a message'); or $redis->publish ('myeest','This is a message');
$redis->psubscribe(['my[ae]est'],'psubscribe');

function psubscribe($redis, $pattern, $chan, $msg) {
      echo "Pattern: $pattern\n";
      echo "Channel: $chan\n";
      echo "Payload: $msg\n";
}

Pattern Matching Rules

The following are supported, with hello as an example:

h?llo subscribes to hello, hallo and hxllo
h*llo subscribes to hllo and heeeello
h[ae]llo subscribes to hello and hallo, but not hillo
Escape Special Characters with\

Introduction to the pubsub method

public function pubsub( $keyword, $argument )

PubsubGets information about the pub/sub system, $keyword can be used as channels, $numsub, or "numpat". Three different keywords return different data

     * $redis->pubsub('channels'); // All channels gets all channels and returns an array
     * $redis->pubsub('channels', '*pattern*'); // Just channels matching your pattern, return channels that match the pattern
     * $redis->pubsub('numsub', array('chan1', 'chan2')); // Get subscriber counts for'chan1'and'chan2' //Returns the number of channels per subscription, returning an array
     * $redis->pubsub('numpat'); // Get the number of pattern subscribers to get the number of subscriptions for pattern matching, that is, $redis->psubscribe (['my[ae]est'],'psubscribe'); return number is 1, $redis->subscribe (['chan'],'callback'); this method is not available, so return number is 0

Reference resources:

Redis Publish Subscription Mode

Keywords: PHP Redis socket

Added by rheroux on Sun, 15 Sep 2019 05:02:13 +0300