Redis入门【八】---------发布与订阅(pub/sub)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Tacks/article/details/82689342

前言

一般来说,发布(publish)与订阅(subscribe),又称为pub/sub的。其特点是订阅者(listener)负责订阅频道(channel),发送者(publisher)负责向频道发送二进制字符串消息。

每当有消息发送到频道的时候,频道的所有订阅者都会收到消息,其实我们可以把频道理解为电台,订阅者可以同时收听多个电台,而发送者可以再任何电台发送消息

频道的订阅与信息发送

下面就是订阅的一个关系,三个客户端同时去订阅subscribe一个频道channel

这时候通过命令publish向频道chnnel发送信息的时候,其他三个客户端就会收到同样的信息。

常用命令

#<1>订阅一个或者多个指定的频道
subscribe channel [channel ...]
#<2>退订给定的一个或多个频道,如果没有指定则表示退订所有的
unsubscribe [channel [channel ...]]
#<3>给定频道发送消息
publish channel message
#<4>订阅给定模式相匹配的所有频道
psubscribe pattern [pattern ...]
#<5>退订给定的模式,如果没有给定则表示退订所有模式
punsubscribe [pattern [pattern ...]]

具体操作

内部实现

订阅

每个 Redis 服务器进程都维持着一个表示服务器状态的 redis.h/redisServer 结构, 结构的 pubsub_channels 属性是一个字典, 这个字典就用于保存订阅频道的信息

扫描二维码关注公众号,回复: 4584279 查看本文章
struct redisServer {
    dict *pubsub_channels;
    // ...
};

某个客户端订阅频道的时候,redis需要将该频道和该客户端绑定。首先,在客户端结构体client中,有一个属性为pubsub_channels,该属性表明了该客户端订阅的所有频道,它是一个字典类型,通过哈希表实现,其中的每个元素都包含了一个键值对以及指向下一个元素的指针,每次订阅都要向其中插入一个结点,键表示订阅的频道值为空

然后,在表示服务器端的结构体redisServer中,也有一个属性为pubsub_channels,但此处它表示的是该服务器端中的所有频道以及订阅了这个频道的客户端,它也是一个字典类型,插入结点时,键表示频道值则是订阅了这个频道的所有客户端组成的链表。最后Redis通知客户端其订阅成功。 

例如client2,client5,client1都订阅了channel频道,而其他频道也分别被别的客户端所订阅,就是下面的场景

服务端中所有频道与客户端的关系

通过 pubsub_channels 字典, 程序只要检查某个频道是否为字典的键, 就可以知道该频道是否正在被客户端订阅; 只要取出某个键的值, 就可以得到所有订阅该频道的客户端的信息。

发送

当调用 publish channel message 命令, 程序首先根据 channel 定位到字典的键, 然后将信息发送给字典值链表中的所有客户端。比如说,对于上面的例子,如果某个客户端执行命令 publish channel1 "hello redis" ,那么 client2 、 client5 和 client1 三个客户端都将接收到 "hello redis" 信息

退订

使用unscribe命令可以退订指定的频道, 这个命令执行的是订阅的反操作: 它从 pubsub_channels 字典的给定频道(键)中, 删除关于当前客户端的信息, 这样被退订频道的信息就不会再发送给这个客户端。

猜你喜欢

转载自blog.csdn.net/Tacks/article/details/82689342