ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

详解Redis —— 发布与订阅(下)

2022-01-06 16:02:14  阅读:227  来源: 互联网

标签:订阅 频道 pattern Redis channels 详解 channel pubsub


文章目录

1-3

见博客 详解Redis —— 发布与订阅(上)

4 发送消息

当一个Redis客户端执行PUBLISH 命令将消息message发送给频道channel的时候,服务器需要执行以下两个动作:
1 )将消息message发送给channel频道的所有订阅者。
2)如果有一个或多个模式pattern与频道channel相匹配,那么将消息message 发送给pattern模式的订阅者。
接下来的两个小节将分别介绍这两个动作的实现方式。

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

因为服务器状态中的pubsub_channels字典记录了所有频道的订阅关系,所以为了将消息发送给channel频道的所有订阅者,PUBLISH命令要做的就是在pubsub_channels字典里找到频道channel的订阅者名单(一个链表), 然后将消息发送给名单上的所有客户端。伪代码如下图所示:

def channel_publish (channel, message) :
	#如果channel键不存在于pubsub_channels字典中
	#那么说明channel频道没有任何订阅者
	#程序不做发送动作,直接返回
	if channel not in server.pubsub_channels:
		return
	#运行到这里,说明channel频道至少有一个订阅者
	#程序遍历channel频道的订阅者链表
	#将消息发送给所有订阅者
	for subscriber in server.pubsub_channels[channel] :
		send_message(subscriber, message)

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

因为服务器状态中的pubsub_patterns 链表记录了所有模式的订阅关系,所以为了将消息发送给所有与channel频道相匹配的模式的订阅者,PUBLISH命令要做的就是遍历整个pubsub_patterns 链表,查找那些与channel频道相匹配的模式,并将消息发送给订阅了这些模式的客户端。
PUBLISH命令将消息发送给模式订阅者的方法可以用以下伪代码来描述:

def pattern_publish (channel, message) :
#遍历所有模式订阅消息
for pubsubPattern in server.pubsub_patterns:
	#如果频道和模式相匹配
	if match (channel, pubsubPattern.pattern) :
		#那么将消息发送给订阅该模式的客户端
		send_message(pubsubPattern.client, message) 

最后,PUBLISH命令的实现可以用以下伪代码来描述:

def publish (channel, message) :
	#将消息发送给channel频道的所有订阅者
	channel_publish (channel, message)
	#将消息发送给所有和channel频道相匹配的模式的订阅者
	pattern_publish (channel, message)

5 查看订阅信息

PUBSUB命令是Redis2.8新增加的命令之–,客户端可以通过这个命令来查看频道或者模式的相关信息,比如某个频道目前有多少订阅者,又或者某个模式目前有多少订阅者,诸如此类。
以下三个小节将分别介绍PUBSUB命令的三个子命令,以及这些子命令的实现原理。

5.1 PUBSUB CHANNELS

PUBSUB CHANNELS [pattern]子命令用于返回服务器当前被订阅的频道,其中pattern参数是可选的:

  • 如果不给定pattern参数,那么命令返回服务器当前被订阅的所有频道。
  • 如果给定pattern参数,那么命令返回服务器当前被订阅的频道中那些与pattern模式相匹配的频道。

这个子命令是通过遍历服务器pubsub_channels字典的所有键(每个键都是一个被订阅的频道),然后记录并返回所有符合条件的频道来实现的,这个过程可以用以下伪代码来描述:

def pubsub_channels (pattern=None) :
	#一个列表,用于记录所有符合条件的频道
	channel_list = []
	#遍历服务器中的所有频道
	# (也即是pubsub_channels字典的所有键)
	for channel in server.pubsub_channels:
		#当以下两个条件的任意一个满足时,将频道添加到链表里面:
		#1 )用户没有指定pattern参数
		#2 )用户指定了pattern参数,并且channel和pattern匹配
		if (pattern is None) or match(channel, pattern) :
		channel_list.append(channel)
	#向客户端返回频道列表
	return channel_list

5.2 PUBSUB NUMSUB

PUBSUB NUMSUB [channel-1 channel-2 … channel-n]子命令接受任意多个频道作为输入,并返回这些频道的订阅者数量。
这个子命令是通过在pubsub_ channels 字典中找到频道对应的订阅者链表,然后返回订阅者链表的长度来实现的(订阅者链表的长度就是频道订阅者的数量),这个过程可以用以下伪代码来描述:

def pubsub_numsub (*all_input_channels) :
	#遍历输入的所有频道
	for channel in all_input_channels:
		#如果pubsub_channels 字典中没有channel这个键
		#那么说明channel频道没有任何订阅者
		if channel not in server.pubsub_channels:
			#返回频道名
			reply_channel_name(channel)
			#订阅者数量为0
			reply_subscribe_count (0)
			#如果pubsub_channels 字典中存在channel键
			#那么说明channel频道至少有一个订阅者
		else:
			#返回频道名
			reply_channel_name(channel) 
			#订阅者链表的长度就是订阅者数量
			reply_subscribe_count(len(server.pubsub_channels[channel]) )

5.3 PUBSUB NUMPAT

PUBSUB NUMPAT 子命令用于返回服务器当前被订阅模式的数量。
这个子命令是通过返回pubsub_ patterns 链表的长度来实现的,因为这个链表的长度就是服务器被订阅模式的数量,这个过程可以用以下伪代码来描述:

def pubsub_numpat () :
	# pubsub_ patterns 链表的长度就是被订阅模式的数量
	reply_pattern_count(len(server.pubsub_patterns) )

标签:订阅,频道,pattern,Redis,channels,详解,channel,pubsub
来源: https://blog.csdn.net/qq_41010280/article/details/122330923

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有