發(fā)布與訂閱
Redis
的發(fā)布訂閱基于publish
,subscribe
,psubscribe
訂閱
subscribe "news.it"
發(fā)布
publish "news.it" "hello"
訂閱
發(fā)布
訂閱的狀態(tài)的推進(jìn)
向
new.it
發(fā)送消息
1.頻道訂閱和退訂
Redis
訂閱關(guān)系保存在服務(wù)器狀態(tài)的pubsub_channels
字典
key
為channel
,value
為鏈表,鏈表上有訂閱該頻道的Client
struct redisServer{
//...
//保存頻道的訂閱關(guān)系
dict *pubsub_channels
//...
}
如圖所示
1.1訂閱頻道subscribe
Client
訂閱pubsub_channels
有兩種情況
- 頻道有其他訂閱者,把
value
添加到鏈表尾部 - 沒有訂閱者,就把先創(chuàng)建
key
再添加value
subscribe "news.sport" "news.movie"
偽代碼
def subscribe (*all input channels):
# 遍歷輸入的所有頻道
for channel in all input channels:
# 如果channel 不存在于pubsub channels 字典(沒有任何訂間者)
# 那么在宇典中添加channel 鍵,井設(shè)置它的值為空鏈表
if channel not in server.pubsub channels:
server.pubsub channels [channel) = (1
# 將訂閱者添加到頻道所對(duì)應(yīng)的鏈表的未尾
server.pubsub channels [channel].append (client)
1.2 退訂頻道
unsubscribe "news.sport" "news.movie"
偽代碼
def unsubscribe (*all input channels):
#遍歷要退訂的所有頻道
for channel in all input channels :
# 在訂閱者鏈表中副除退訂的客戶端
server . pubsub channels [channel1. remove (client)
# 如果頻道已經(jīng)沒有任何訂閱者了(訂間者鏈表為空)
# 那么將頻道從字典中刷除
if len (server.pubsub channels [channel]) == 0 :
server.pubsub channels. remove (channel)
2.模式訂閱和退訂
struct redisServer{
// ...
//保持所有模式訂閱關(guān)系
list *pubsub_patterns;
// ...
}
pubsub_patterns
是鏈表,每個(gè)節(jié)點(diǎn)都包括一個(gè)pubsub_Patterns
結(jié)構(gòu)
typedef struct pubsubPattern{
//訂閱模式Client
redisClient *client;
//被訂閱的模式
robj *pattern;
}
示意圖
client-7,8,9分別在訂閱 music.*,book.*,news.*
2.1訂閱模式psubscribe
客戶端執(zhí)行
psubscribe
,服務(wù)端會(huì)執(zhí)行兩個(gè)操作
- 新建
pubsubPattern
,講結(jié)構(gòu)的pattern
設(shè)置為被訂閱的模式 - 將
pubsubPattern
添加到pubsub_patterns
鏈表尾部
執(zhí)行
psubscribe
之前的pubsub_patterns
執(zhí)行
psubscribe
之后的pubsub_patterns
def subscribe (*all_ input patterns):
#遍歷輸入的所有模式
for pattern in all input patterns:
#創(chuàng)建新的 pubsubPattern 結(jié)構(gòu)
# 記錄被訂間的模式,以及訂閱模式的容戶端
pubsubPattern = create new pubsubPattern (
pubsubPattern.client= client
pubsubPattern.pattern= pattern
# 將新的 pubsubPattern 追加到pubsubpatterns鏈表末尾
server.pubsub patterns.append (pubsubPattern)
2.2 退訂模式
punsubscribe
當(dāng)執(zhí)行退訂模式的時(shí)候,相應(yīng)的
pubsubPattern
結(jié)構(gòu)會(huì)被刪除
執(zhí)行
punsubscribe "news.*"
之前的pubsub_patterns
執(zhí)行
punsubscribe "news.*"
之后的pubsub_patterns
def unsubscribe (*all input patterns) :
# 遍歷所有要退訂的模式
for pattern in all input patterns:
# 遍歷 pubsub patterns 鏈表中的所有pubsubPattern 結(jié)構(gòu)
for pubsubPattern in server.pubsub patterns:
#如果當(dāng)前客戶端和pubsuibPattern 記錄的客戶端相同
#并且要退訂的模式也和 pubsubPattern 記錄的模式相同
if client == pubsubPattern.client and \
pattern == pubsubPattern.pattern:
# 那么將這個(gè)pubsubPattern 從鏈表中利除
server.pubsub patterns.remove (pubsubPattern)
3.發(fā)送消息
PUBLISH <channel> <message>
將
message
發(fā)送到channel
的訂閱者
一個(gè)或多個(gè)
pattern
與頻道channel
匹配
3.1 消息發(fā)送頻道訂閱者
PUBLISH "news.it" "hello" // client-1,client-2,client-3都會(huì)收到
偽代碼
def channel_publish (channel, message) :
# 如果 channel鍵不存在于pubsub channels 字典中
# 那么說明 channe1 頻道沒有任何訂鬩者
# 程序不做發(fā)送動(dòng)作,直接返回
if channel not in server.pubsub channels:
return
# 運(yùn)行到這里,說明 channel 頻道至少有一個(gè)訂閱者
# 程序遍歷 channe1 頻道的訂閱者鏈表
# 將消,息發(fā)送給所有訂閱者
for subscriber in server.pubsub channels [channel] :
send message (subscriber, message)
3.2消息發(fā)送模式訂閱者
PUBLISH "news.it" "hello" // 和news.*匹配,news.*會(huì)收到
偽代碼
def pattern_publish (channel, message):
# 遍歷所有模式訂閱消息
for pubsubPattern in server.pubsub patterns:
# 如果頻道和模式相匹配
if match (channel, pubsubPattern.pattern):
#那么格消息發(fā)洪給訂回該模式的容戶瑞
send message (pubsubPattern.client, message)
總結(jié)的Publish
def publish (channel, message):
# 將消息發(fā)送給 channe1 頻道的所有訂間者
channel publish (channel, message)
#將消息發(fā)送給所有和 channel 頻道相匹配的模式的訂回者
pattern publish (channel, message)
4.查看訂閱消息
PUBSUB查看頻道或者模式相關(guān)消息
4.1 pubsub channels
pubsub channels <pattern>(可選) //pattern可選,選擇表示返回匹配的頻道
def pubsub channels (pattern=None) :
#一個(gè)列表,用于記錄所有符合條件的頻道
channel_list = []
# 遍歷服務(wù)器中的所有頻道
#(也即是pubsub channels 字典的所有鍵)
for channel in server.pubsub channels:
# 當(dāng)以下兩個(gè)條件的任意一個(gè)滿足時(shí),將頻道添加到鏈表里面:
#1 )用戶沒有指定pattezn 參數(shù)
#2 )用戶指定了pattern 參數(shù),并且channel 和pattern 匹配
if (pattern is None) or match (channel, pattern):
channel list.append (channel)
# 向客戶端返回頻道列表
return channel_list
被訂閱的4個(gè)頻道
redis> PUBSUB CHANNELS
1)"news. it"
2)"news.sport"
3)"news. business"
4)"news.movie"
進(jìn)行頻道
pattern
篩選
redis> PUBSUB CHANNELS "news. [is]*"
//返回所有名稱以"news."開頭,并且后面緊跟著一個(gè)或多個(gè)字母"i"或"s"的頻道的列表
1)"news.it"
2)"news. sport"
4.2 pubsub numsub
pubsub numsub [channel-1 channel-2 ...channel-n] //接受多個(gè)頻道作為入?yún)?,返回這些頻道的訂閱者
偽代碼
def pubsub numsub (*all input channels) :
# 遍歷輸入的所有頻道
for channel in all input channels:
#如果 pubsub channels 宇典中沒有 channe1 這個(gè)鍵
#那么說明 channel 頻道沒有任何訂回者
if channel not in server.pubsub channels:
#返回頻道名
reply channel name (channel)
# 訂閱者數(shù)量為。
reply subscribe count (0)
#如果 pubsub channels 字典中存在 channe1 鍵
# 那么說明channel 頻道至少有一個(gè)訂閱者
else:
#返回頻道名
reply channel name (channel)
# 訂閱者鏈表的長(zhǎng)度就是訂用者數(shù)量
reply subscribe count (len (server .pubsub_channels [channel]))
redis> PUBSUB NUMSUB news.it news.sport news.business news.movie
1)"news. it"
2)"3"
3)"news. sport"
4)"2"
5)"news.business"
6)"2"
7)"news. movie"
8)"1"
4.3 pubsub numpat
返回服務(wù)器當(dāng)前被訂閱模式的數(shù)量
偽代碼
def pubsub_numpat():
# pubsub_patterns 鏈表長(zhǎng)度是被訂閱數(shù)量
reply pattern count (len(server.pubsub patterns))
文章來源:http://www.zghlxwxcb.cn/news/detail-635750.html
對(duì)于上方鏈表來說,執(zhí)行
pubsub numpat
結(jié)果文章來源地址http://www.zghlxwxcb.cn/news/detail-635750.html
redis> pubsub numpat
(integer) 3
5.回顧
- 服務(wù)器在
pubsub_channels
保存頻道訂閱關(guān)系,subscribe
和unsubscribe
- 服務(wù)器在
pubsub_patterns
保存模式訂閱關(guān)系,psubscribe
和punsubscribe
-
publish
發(fā)送消息 -
pubsub
讀取pubsub_channels
和pubsub_patterns
來實(shí)現(xiàn)
到了這里,關(guān)于redis發(fā)布訂閱模型的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!