本节概览:介绍redis pub/sub命令使用和原理。
本文内容来自 https://redisbook.readthedocs.io/en/latest/feature/pubsub.html
1 命令介绍

Redis 的 SUBSCRIBE 命令可以让客户端订阅任意数量的频道, 每当有新信息发送到被订阅的频道时, 信息就会被发送给所有订阅指定频道的客户端。 发送的消息不会保存在Redis服务器里面,所以如果接收消息客户端断连,则会丢失消息。
|
1 2 3 4 |
127.0.0.1:6379> SUBSCRIBE channel1 Reading messages... (press Ctrl-C to quit) 1) "subscribe" 2) "topic_test" |
下图展示了频道 channel1 , 以及订阅这个频道的三个客户端 client2 、 client5 和 client1 之间的关系:

当有新消息通过 PUBLISH 命令发送给频道 channel1 时, 这个消息就会被发送给订阅它的三个客户端:

命令举例

2 实现
2.1 数据结构
redis.h/redisServer 结构, 结构的 pubsub_channels 属性是一个字典, 这个字典就用于保存订阅频道的信息,字典的键为正在被订阅的频道, 而字典的值则是一个链表, 链表中保存了所有订阅这个频道的客户端。|
1 2 3 4 5 |
struct redisServer { // ... dict *pubsub_channels; // ... }; |
比如说,在下图展示的这个 pubsub_channels 示例中, client2 、 client5 和 client1 就订阅了 channel1 , 而其他频道也分别被别的客户端所订阅:

2.2 SUBSCRIBE
当客户端调用 SUBSCRIBE 命令时,程序就将客户端和要订阅的频道在 pubsub_channels 字典中关联起来。如客户端 client10086 执行命令 SUBSCRIBE channel1 channel2 channel3 ,那么前面展示的 pubsub_channels 将变成下面这个样子:

伪代码如下
|
1 2 3 4 5 6 7 |
def SUBSCRIBE(client, channels): # 遍历所有输入频道 for channel in channels: # 将客户端添加到链表的末尾 redisServer.pubsub_channels[channel].append(client) |
2.3 PUBLISH命令
PUBLISH 命令的实现就非常简单了: 当调用 PUBLISH channel message 命令, 程序首先根据 channel 定位到字典的键, 然后将信息发送给字典值链表中的所有客户端。
比如说,对于以下这个 pubsub_channels 实例, 如果某个客户端执行命令 PUBLISH channel1 "hello moto" ,那么 client2 、 client5 和 client1 三个客户端都将接收到 "hello moto" 信息。

伪代码如下
|
1 2 3 4 5 6 7 |
def PUBLISH(channel, message): # 遍历所有订阅频道 channel 的客户端 for client in server.pubsub_channels[channel]: # 将信息发送给它们 send_message(client, message) |




