redis设计与实现读书笔记——发布与订阅
频道的订阅与退订
Redis将所有频道的订阅关系都保存在服务器状态的pubsub_channels字典里面,这个字典的键是某个被订阅的频道,而键的值则是一个链表,链表里面记录了所有订阅这个频道的客户端。
struct redisServer{
//……
//保存所有频道的订阅关系
dict *pubsub_channels;
//……
};
- 订阅频道
每当客户端执行SUBSCRIBE命令订阅某个或某些频道的时候,服务器都会将客户端与被订阅频道在pubsub_channels字典中进行关联。
def subscribe(*all_input_channels)
#遍历输入的所有频道
for channel in all_input_channels;
#如果channel不存在于pubsub_channels字典,则在字典中添加该键,并设置它的值为空链表
if channel not in server.pubsub_channels:
server.pubsub_channels[channel]=[]
#将订阅者添加到频道所对应的链表的末尾
server.pubsub_channels[channel].append(client)
- 退订频道
UNSUBSCRIBE命令的行为和SUBSCRIBE命令的行为正好相反,当一个客户端退订某个或某些频道的时候,服务器将从pubsub_channels中解除客户端与被退订频道之间的关联。
def unsubscribe(*all_input_channels)
#遍历要退订的的所有频道
for channel in all_input_channels;
#在订阅者链表中删除退订的客户端
server.pubsub_channels[channel].remove(client)
#如果频道中已经没有任何订阅者了,那么将频道从字典中删除
if len(server.pubsub_channels[channel]) == 0:
server.pubsub_channels.remove(channel)
模式的订阅与退订
Redis将所有模式的订阅关系都保存在服务器状态的pubsub_patterns属性里面
struct redisServer{
//……
//保存所有模式的订阅关系
list *pubsub_patterns;
//……
};
- 订阅模式
def psubscribe(*all_input_patterns)
#遍历输入的所有模式
for pattern in all_input_patterns;
#创建新的pubsubPattern结构,记录被订阅的模式,以及订阅模式的客户端
pubsubPattern = create_new_pubsubPattern()
pubsubPattern.client = client
pubsubPattern.pattern = pattern
#将新的pubsubPattern追加到pubsub_patterns链表末尾
server.pubsub_patterns.append(pubsubPattern)
- 退订模式
def punsubscribe(*all_input_patterns)
#遍历所有要退订的模式
for pattern in all_input_patterns;
#遍历subpub_patterns链表中的所有pubsubPattern结构
for pubsubPattern in server.pubsub_patterns:
#如果当前客户端与subpubPattern记录的客户端相同
#并且退订的模式也和pubsubPattern记录的模式相同
if client == pubsubPattern.clent and pattern = pubsubPattern.pattern
#将这个pubsubPattern删除
server.pubsub_patterns.remove(pubsubPattern)
发送消息
当一个Redis客户端执行PUBLISH <channel> <message>命令将消息message发送给频道channel的时候,服务器需要执行以下两个动作:
- 将消息message发给channel频道的所有订阅者
- 如果有一个或者多个模式pattern与频道channel相匹配,那么将消息message发送给pattern模式的订阅者
def channel_publish(channel,message)
#如果模式不存在于pubsub_channels字典中,直接返回
if channel not in server.pubsub_channels
return
#遍历channel频道的订阅者链表,将消息发送给链表中的每一个订阅者
for subscriber in server.pubsub_channels[channel]
send_message(subscriber,message)
===========================================================================
def pattern_publish(channel,message)
#遍历所有模式订阅消息
for pubsubpattern in server.pubsub_patterns
#如果频道和模式相匹配
if match(channel,pubsubPattern.pattern):
#那么将消息发送给该模式的客户端
send_message(pubsubPattern.client,message)
============================================================================
def publish(channel,message)
channel_publish(channel,message)
pattern_publish(channel,message)
查看订阅消息
- PUBSUB CHANNELS
PUBSUB CHANNELS [pattern] 子命令用于返回服务器当前被订阅的频道,其中pattern参数是可选的:如果不给定pattern参数,那么命令返回服务器当前被订阅的所有频道;如果给定pattern参数,那么命令返回服务器当前被订阅的频道中与pattern模式相匹配的频道。
- PUBSUB NUMSUB
PUBSUB NUMSUB [channel-1 channel-2 …… channel-n]子命令接受任意多个频道作为输入参数,并返回这些频道的订阅者数量。
- PUBSUB NUMPAT
PUBSUB NUMPAT子命令用于返回服务器当前被订阅模式的数量。
上一篇: php操作mysql事务深度测试
下一篇: vue组件基础使用方法有哪些