Redis is well suited to supporting the Publish/Subscribe (Pub/Sub) model where publisher applications sends messages to one or more channels that subscriber applications monitor and then react to the messages that posted to the channel.
An important limitation of Pub/Sub that does NOT necessary guarantee the delivery of messages i.e. Redis Pub/Sub is fire and forget. Messages published to a channel are not assured to be delivered to the client monitoring the channel by subscription.
Running a single Redis instance, we launch two redis-cli
sessions, the first client will have the publisher role and the second
client will have the consumer role.
redis-cli
$ ../redis/src/redis-cli 127.0.0.1:6379> PUBLISH user:1:msgs "How is everything?" (integer) 1
redis-cli
$ ../redis/src/redis-cli 127.0.0.1:6379> SUBSCRIBE user:1:msgs user:2:msgs Reading messages... (press Ctrl-C to quit) 1) "subscribe" 2) "user:1:msgs" 3) (integer) 1 1) "subscribe" 2) "user:2:msgs" 3) (integer) 2 1) "message" 2) "user:1:msgs" 3) "How is everything?"
Redis Pub/Sub messages are defined as 3 or 4 part RESP (REdis Serialization Protocol) array. RESP is the communication protocol that Redis client communicate with Redis server and is used in other projects beside Redis. We see the raw RESP protocol if we use telnet and connect directly to Redis.
First, we will connect to a single Redis instance running at port 6379 with telnet.
$ telnet localhost 6379 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'.
Now, we will subscribe to a chat_room channel
and from aredis-cli
session, we will post a message to the channel.
SUBSCRIBE chat_room *3 $9 subscribe $9 chat_room :1 *3 $7 message $9 chat_room $18 Anybody out there?
To subscribe to more than one channel, you can use the PSUBSCRIBE that take a pattern to match to existing channels.
PSUBSCRIBE chat_* *3 $10 psubscribe $6 chat_* :1 *4 $8 pmessage $6 chat_* $9 chat_room $18 What is your name?
To unsubscribe to multiple channels at once, you can use the PUNSUBSCRIBE
PUNSUBSCRIBE chat* *3 $12 punsubscribe $5 chat* :1
To experiment with Pub/Sub and Redis Cluster, we will use a Python Redis Cluster for a simple client consumer.
>>> from rediscluster import StrictRedisCluster >>> startup_nodes = [{"host": "127.0.0.1", "port": "7001"}] >>> messenger_cluster = StrictRedisCluster(startup_nodes=startup_nodes, decode_response=True) >>> person_consumer = messenger_cluster.pubsub() >>> person_consumer.subscribe("chat_room") >>> person_consumer.get_message() {'channel': 'chat_room', 'type': 'message', 'data': "What's happening?", 'pattern': None}