第十八章 发布与订阅
通过SUBSCRIBE命令,客户端可以订阅一个或多个频道,每当有其他客户端向被订阅的频道发送消息,频道的订阅者都会收到消息
通过PSUBSCRIBE命令,客户端可以订阅一个或多个模式,每当有其他客户端向被订阅的频道发送消息,与该频道相匹配的模式订阅者也会收到
18.1 频道的订阅和退订
redisServer中用一个字典保存了所有频道的订阅关系,字典的键是频道名,字典的值是一个链表,保存了订阅的客户端
struct redisServer{ //保存所有频道的订阅消息 dict *pubsub_channels; //.... }
18.1.1 订阅频道
将频道和对应的客户端插入字典pubsub_channels中,若已有将新加入的客户端放到链表表尾
18.1.2 退订频道
在字典中找到对应的键,遍历链表删除相应的客户端,删除之后成了空链表,则删除对应的键
18.2 模式的订阅和退订
redisServer中用一个链表保存了所有模式的订阅关系
struct redisServer{ //保存所有模式订阅模式 list *pubsub_patterns; //... };
链表的每个节点包含了一个pubsubPattern结构
typedef struct pubsubPattern{ //订阅模式的客户端 redisClient *client; //被订阅的模式 robj *pattern; }pubsubPattern;
18.2.1 订阅模式
客户端执行PSUBSCRIBE命令订阅某个模式,服务器会新建一个pubsubPattern对象,插入到pubsub_patterns链表的末尾
18.2.2 退订模式
在pubsub_patterns中查到所属的节点并删除
18.3 发送消息
客户端执行PUBLISH <channel> <message>
18.3.1 将消息发送给频道订阅者
从pubsub_channels字典中找到对应的键,取出值对象(一个链表),遍历链表,找到对应频道下的所有订阅者,将消息发送往这些订阅者
18.3.2 将消息发送给模式订阅者
查找链表,找出匹配模式的订阅者,将消息发送给订阅者
后记:
缺点:不持久化消息,不保证客户端一定接收到消息
人生就像蒲公英,看似自由,其实身不由己。