Redis发布与订阅功能由PUBLISH,SUBSCRIBE,PSUBSCRIBE等命令组成。

【SUBSCRIBE命令】

客户端可以订阅一个或多个频道,从而成为这些频道的订阅者(subscriber)。

每当有其他客户端向被订阅的频道发送消息时,频道的所有订阅者都会收到这条消息。

【Redis笔记】发布与订阅_客户端

 

【实现】

Redis所有频道的订阅关系都保存在服务器状态的pubsub_channels字典里面,这个字典的键是某个被订阅的频道,值是一个链表,记录了所有订阅这个频道的客户端。

每当客户端执行SUBSCRIBE命令订阅某个或某些频道时,服务器都会将客户端与被订阅的频道与pubsub_channels字典进行关联。

如果频道有订阅者,把客户端加到订阅者链表的末尾。

如果频道没有订阅者,新建一个链表,把客户端加到链表,称为链表第一个元素。

【Redis笔记】发布与订阅_redis_02

【UNSUBSCRIBE命令】

客户端退订某个或某些频道。

服务器将从pubsub_channels中解除客户端与被退订频道之间的关联。

程序会根据被退订频道的名字,在pubsub_channels字典中找到频道对应的订阅者链表,然后从订阅者链表中删除退订客户端信息。

如果删除退订客户端之后,频道的订阅者链表变成了空链表,那么说明这个频道已经没有任何订阅者了,程序将从pubsub_channels字典中删除频道对应的键。

【PSUBSCRIBE命令】

客户端可以订阅一个或多个模式,从而成为这些模式的订阅者。

每当有其他客户端向某个频道发送消息时,消息不仅会被发送给这个频道的所有订阅者,还会被发送给所有与这个频道相匹配的订阅者。

【Redis笔记】发布与订阅_客户端_03

 

【Redis笔记】发布与订阅_客户端_04

 

【实现】

服务器将所有模式的订阅关系保存在服务器状态的pubsub_patterns属性里面。

pubsub_patterns属性是一个链表,链表中的每一个节点都包含了一个pubsubPattern结构,这个结构的pattern属性记录了被订阅的模式,client属性记录了订阅模式的客户端。

每当客户端执行PSUBSCRIBE命令订阅某个或某些模式的时候

服务器会

(1)新建一个pubsubPattern结构,将结构的pattern属性设置为被订阅的模式,client属性设置为订阅模式的客户端。

(2)将pubsubPattern结构添加到pubsub_patterns链表的末尾。

 

【Redis笔记】发布与订阅_链表_05

【PUNSUBSCRIBE命令】

当一个客户端退订某个或某些模式时,服务器会在pubsub_patterns链表中查找并删除pattern和client属性都匹配的节点,

【PUBLISH命令】

将消息message发送给channel频道的所有订阅者

如果有一个或多个模式pattern与模式channel相匹配,那么将消息message发送给pattern模式的订阅者。(遍历链表并判断)

【查看订阅信息】

【PUBSUB CHANNELS】返回服务器当前被订阅的频道。

可选参数pattern。

如果没有pattern参数,命令返回服务器当前被订阅的所有频道。

如果有pattern参数,命令返回服务器当前被订阅的频道中与pattern模式相匹配的频道。

实现:遍历pubsub_channels字典的所有键

【PUBSUB NUMSUB】接受任意多个频道作为参数,并返回这些频道的订阅者数量

实现:返回订阅者链表的长度

【PUBSUB NUMPAT】返回服务器当前被订阅模式的数量