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) )