Redis的发布与订阅功能由publish、subscribe、psubscribe、等命令组成

通过执行命令,客户端可以订阅一个或多个频道,从而成为这些频道的订 阅者(subscriber):每当有其他客户端向被订阅的频道发送消息(message)时,频道的所 有订阅者都会收到这条消息

ios combine 发布者绑定订阅者_链表

ios combine 发布者绑定订阅者_客户端_02

ios combine 发布者绑定订阅者_客户端_03

ios combine 发布者绑定订阅者_客户端_04

ios combine 发布者绑定订阅者_客户端_05

 

一、频道的订阅与退订

当一个客户端执行命令订阅某个或某些频道的时候,这个客户端与被订阅 频道之间就建立起了一种订阅关系

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

ios combine 发布者绑定订阅者_客户端_06

1.1 订阅频道

 每当客户端执行命令订阅某个或某些频道的时候,服务器都会将客户端与 被订阅的频道在pubsub_channels字典中进行关联
            如果频道已经有其他订阅者,那么它在pubsub_channels字典中必然有相应的订 阅者链表,程序唯一要做的就是将客户端添加到订阅者链表的末尾(链表上仅有client这一个属性)
            如果频道还未有任何订阅者,那么它必然不存在于pubsub_channels字典,程序 首先要在pubsub_channels字典中为频道创建一个键,并将这个键的值设置为空 链表,然后再将客户端添加到链表,成为链表的第一个元素

ios combine 发布者绑定订阅者_客户端_07

1.2退订频道

当一个客户端退订某 个或某些频道的时候,服务器将从pubsub_channels中解除客户端与被退订频道之间的 关联
            程序会根据被退订频道的名字,在pubsub_channels字典中找到频道对应的订阅 者链表,然后从订阅者链表中删除退订客户端的信息
            如果删除退订客户端之后,频道的订阅者链表变成了空链表,那么说明这个频道已 经没有任何订阅者了,程序将从pubsub_channels字典中删除频道对应的键

ios combine 发布者绑定订阅者_客户端_08

ios combine 发布者绑定订阅者_链表_09

二、模式的订阅与退订

  服务器将所有频道的订阅关系都保存在服务器状态的pubsub_channels 属性里面,与此类似,服务器也将所有模式的订阅关系都保存在服务器状态的pubsub_ patterns属性里面

2.1 订阅模式

每当客户端执行命令订阅某个或某些模式的时候,服务器会对每个被订 阅的模式执行以下两个操作
            新建一个pubsubPattern结构,将结构的pattern属性设置为被订阅的模式, client属性设置为订阅模式的客户端(链表上有clent和patten两个属性)
            将pubsubPattern结构添加到pubsub_patterns链表的表尾

ios combine 发布者绑定订阅者_服务器_10

ios combine 发布者绑定订阅者_客户端_11

2.2 退订模式

模式的退订命令PUNSUBCREIBE是命令PSUBCREIBE的反操作:当一个客户端退订某 个或某些模式的时候,服务器将在pubsub_patterns链表中查找并删除那些pattern 属性为被退订模式,并且client属性为执行退订命令的客户端的pubsubPattern结构

ios combine 发布者绑定订阅者_服务器_12

ios combine 发布者绑定订阅者_链表_13

 

三、发送消息

当一个 Redis 客户端执行 PUBLISH〈channel〉〈message〉命令将消息 message 发送给频道channel的时候,服务器需要执行以下两个动作
            将消息message发送给channel频道的所有订阅者
            如果有一个或多个模式pattern与频道channel相匹配,那么将消息message 发送给pattern模式的订阅者

3.1 将消息发送给频道订阅者

因为服务器状态中的pubsub_channelS字典记录了所有频道的订阅关系,所以为 了将消息发送给Charmel频道的所有订阅者,命令要做的就是在pUbsub_ channels字典里找到频道channel的订阅者名单(一个链表),然后将消息发送给名单 上的所有客户端

ios combine 发布者绑定订阅者_服务器_14

3.2 将消息发送给模式订阅者

服务器状态中的pubsub_patterns链表记录了所有模式的订阅关系,所以为了 将消息发送给所有与channel频道相匹配的模式的订阅者,命令要做的就是遍 历整个pubsub_patterns链表,査找那些与channel频道相匹配的模式,并将消息发 送给订阅了这些模式的客户端。

ios combine 发布者绑定订阅者_服务器_15

 

四、查看订阅信息

客户端可以通过PUBSUB命令来查看频道或 者模式的相关信息,比如某个频道目前有多少订阅者,又或者某个模式目前有多少订阅者

 4.1 PUBSUB CHANNELS

PUBSUB CHANNELS[parttern]命令用于返回服务器当前被订阅的频道,其中pattern参数是可选的
            如果不给定pattern参数,那么命令返回服务器当前被订阅的所有频道
            如果给定pattern参数,那么命令返回服务器当前被订阅的频道中那些与pattern 模式相匹配的频道

 4.2 PUBSUB NUMSUB

PUBSUB NUMSUB[parttern-1 parttern-2 ... parttern-N]子命令接收任意多个频道作为输入参数,并返回这些频道的订阅者数量。
        这个子命令是通过在pubsub_channels字典中找到频道对应的订阅者链表,然后返 回订阅者链表的长度来实现的(订阅者链表的长度就是频道订阅者的数量)

4.2 PUBSUB NUMPAT

 PUBSUB NUMPAT子命令用于返回服务器当前被订阅模式的数量
        这个子命令是通过返回pubsub_patterns链表的长度来实现的,因为这个链表的长 度就是服务器被订阅模式的数量