Redis - publish and subscribe

Posted by damo87 on Thu, 06 Jan 2022 09:06:54 +0100

1-3

See blog Detailed explanation of Redis - publish and subscribe (Part I)

4 send message

When a Redis client executes the PUBLISH command to send a message to the channel, the server needs to perform the following two actions:
1) send message to all subscribers of channel channel.
2) If one or more patterns match the channel, the message message is sent to the subscriber of the pattern pattern.
The next two sections will introduce the implementation of these two actions respectively.

4.1 sending messages to channel subscribers

Because PubSub in server state_ The channels dictionary records the subscription relationship of all channels. Therefore, in order to send messages to all subscribers of channel channels, the PUBLISH command needs to do in PubSub_ Find the subscriber list (a linked list) of the channel in the channels dictionary, and then send the message to all clients on the list. The pseudo code is shown in the figure below:

def channel_publish (channel, message) :
	#If the channel key does not exist in pubsub_channels dictionary
	#It means that there are no subscribers to the channel
	#The program does not send, but returns directly
	if channel not in server.pubsub_channels:
		return
	#Running here indicates that the channel has at least one subscriber
	#The program traverses the subscriber list of channel channels
	#Send message to all subscribers
	for subscriber in server.pubsub_channels[channel] :
		send_message(subscriber, message)

4.2 sending messages to schema subscribers

Because PubSub in server state_ The patterns linked list records the subscription relationship of all patterns. Therefore, in order to send messages to all subscribers of patterns matching the channel channel, the PUBLISH command needs to traverse the whole pubsub_patterns linked list, find the patterns that match the channel channel, and send messages to the clients who subscribe to these patterns.
The method by which the PUBLISH command sends a message to the schema subscriber can be described by the following pseudocode:

def pattern_publish (channel, message) :
#Traverse all schema subscription messages
for pubsubPattern in server.pubsub_patterns:
	#If the channel and mode match
	if match (channel, pubsubPattern.pattern) :
		#Then send the message to the client subscribing to the pattern
		send_message(pubsubPattern.client, message) 

Finally, the implementation of the PUBLISH command can be described by the following pseudo code:

def publish (channel, message) :
	#Send a message to all subscribers to the channel
	channel_publish (channel, message)
	#Send the message to all subscribers of the pattern matching the channel channel
	pattern_publish (channel, message)

5 view subscription information

The PUBSUB command is redis2 8. The newly added command - the client can use this command to view the relevant information of the channel or mode, such as the current number of subscribers of a channel, or the current number of subscribers of a mode, and so on.
The following three sections will introduce the three subcommands of the PUBSUB command and the implementation principle of these subcommands.

5.1 PUBSUB CHANNELS

The PUBSUB CHANNELS [pattern] subcommand is used to return the channel currently subscribed to by the server, where the pattern parameter is optional:

  • If the pattern parameter is not given, the command returns all channels currently subscribed to by the server.
  • If the pattern parameter is given, the command returns those channels that match the pattern in the channels currently subscribed to by the server.

This subcommand traverses the server PubSub_ All keys of the channels Dictionary (each key is a subscribed channel), and then record and return all qualified channels. This process can be described by the following pseudo code:

def pubsub_channels (pattern=None) :
	#A list that records all eligible channels
	channel_list = []
	#Traverse all channels in the server
	# (that is, all keys of pubsub_channels Dictionary)
	for channel in server.pubsub_channels:
		#When either of the following two conditions is met, the channel will be added to the linked list:
		#1) the user did not specify the pattern parameter
		#2) the user specifies the pattern parameter, and the channel and pattern match
		if (pattern is None) or match(channel, pattern) :
		channel_list.append(channel)
	#Returns the channel list to the client
	return channel_list

5.2 PUBSUB NUMSUB

The PubSub numsub [channel-1, channel-2... channel-n] subcommand accepts any number of channels as input and returns the number of subscribers to these channels.
This subcommand is passed in PubSub_ Find the subscriber list corresponding to the channel in the channels dictionary, and then return the length of the subscriber list (the length of the subscriber list is the number of channel subscribers). This process can be described by the following pseudo code:

def pubsub_numsub (*all_input_channels) :
	#Traverse all input channels
	for channel in all_input_channels:
		#If PubSub_ The key channel is not in the channels dictionary
		#It means that there are no subscribers to the channel
		if channel not in server.pubsub_channels:
			#Return channel name
			reply_channel_name(channel)
			#The number of subscribers is 0
			reply_subscribe_count (0)
			#If PubSub_ The channel key exists in the channels dictionary
			#It means that the channel has at least one subscriber
		else:
			#Return channel name
			reply_channel_name(channel) 
			#The length of the subscriber list is the number of subscribers
			reply_subscribe_count(len(server.pubsub_channels[channel]) )

5.3 PUBSUB NUMPAT

The PUBSUB NUMPAT subcommand returns the number of currently subscribed modes of the server.
This subcommand returns pubsub_ patterns is realized by the length of the linked list, because the length of the linked list is the number of subscribed modes of the server. This process can be described by the following pseudo code:

def pubsub_numpat () :
	# pubsub_  The length of the patterns linked list is the number of subscribed patterns
	reply_pattern_count(len(server.pubsub_patterns) )

Topics: Java Database Redis