成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專(zhuān)欄INFORMATION COLUMN

Redis的發(fā)布與訂閱

nodejh / 1789人閱讀

摘要:的發(fā)布訂閱功能由等命令組成。發(fā)布與訂閱頻道名中國(guó)男籃戰(zhàn)勝了美國(guó)男籃,獲得了奧運(yùn)冠軍訂閱多個(gè)頻道則直接添加該數(shù)組子元素這里除了這條命令之外其它命令都不能使用留意我們接收消息的回調(diào)函數(shù)。那么將消息發(fā)送給模式的訂閱者。

Redis的發(fā)布訂閱功能由 PUBLISH、SUBSCRIBEPSUBSCRIBE等命令組成。

通過(guò)執(zhí)行SUBSCRIBE命令,客戶(hù)端可以訂閱一個(gè)或多個(gè)頻道從而成為這些頻道的訂閱者(subscriber),
當(dāng)有其它客戶(hù)端向被訂閱的頻道發(fā)送消息時(shí),頻道的所有訂閱者都能收到這條消息。

在下圖中客戶(hù)端A、客戶(hù)端B、客戶(hù)端C,分別訂閱了cctv.5這個(gè)頻道。這個(gè)時(shí)候某個(gè)客戶(hù)端執(zhí)行了如下這條命令:

PUBLICH "cctv.5" "中國(guó)男籃戰(zhàn)勝了美國(guó)男籃,獲得了奧運(yùn)冠軍"

此時(shí)訂閱了cctv.5這個(gè)頻道的所有客戶(hù)端都將收到這條消息。


除了訂閱頻道之外,客戶(hù)端還可以通過(guò)執(zhí)行PSUBSCRIBE命令訂閱一個(gè)或多個(gè)模式,從而成為這些模式的訂閱者。每當(dāng)有其他客戶(hù)端向某個(gè)頻道發(fā)送消息時(shí),消息不僅僅會(huì)發(fā)送給這個(gè)頻道的訂閱者,還會(huì)發(fā)送給與這個(gè)頻道相匹配的模式訂閱者。


上圖中,我們給cctv.3這個(gè)頻道發(fā)送了一條消息"同一首歌",該消息首先會(huì)發(fā)送給它的訂閱者client A,然后根據(jù)模式匹配,cctv.3符合cctv.*這個(gè)模式。所以訂閱了cctv.*頻道的訂閱者也都可以收到消息呢。(●′?`●)?

頻道的訂閱

當(dāng)一個(gè)客戶(hù)端執(zhí)行SUBSCRIBE命令訂閱某個(gè)或某些頻道的時(shí)候,這個(gè)客戶(hù)端與被訂閱頻道之間就建立了一種訂閱關(guān)系。

Redis 將所有頻道的訂閱關(guān)系都保存在服務(wù)器狀態(tài)的pubsub_channels字典里面,這個(gè)字典的鍵是某個(gè)被訂閱的頻道,值是一個(gè)鏈表,鏈表里面記錄了所有訂閱這個(gè)頻道的客戶(hù)端。

客戶(hù)端執(zhí)行SUBSCRIBE命令訂閱某個(gè)或某些頻道的時(shí)候,服務(wù)器都會(huì)將客戶(hù)端與被訂閱的頻道在 pubsub_channels 字典中進(jìn)行關(guān)聯(lián)。

根據(jù)頻道是否已經(jīng)有其他訂閱者,關(guān)聯(lián)操作分為兩種情況執(zhí)行:

頻道已經(jīng)有其他訂閱者,那么在pubsub_channels字典中必然有相應(yīng)的訂閱者鏈表。程序唯一要做的是將客戶(hù)端添加到鏈表的末尾。

頻道沒(méi)有其它訂閱者,程序首先要在pubsub_channels字典中為頻道創(chuàng)建一個(gè)鍵,并將值設(shè)置為空鏈表,然后將客戶(hù)端添加到鏈表。成為鏈表的第一個(gè)元素。

php 發(fā)布與訂閱demo

// publish.php
connect("127.0.0.1",6379);
    // 頻道名
    $channel = "cctv.5";
    $message = "中國(guó)男籃戰(zhàn)勝了美國(guó)男籃,獲得了奧運(yùn)冠軍";
    $Redis->publish($channel,$message);
?>

// subscribe.php
connect("127.0.0.1",6379);
    $channel = ["cctv.5"];    // 訂閱多個(gè)頻道則直接添加該數(shù)組子元素
    $Redis->subscribe($channel,function($instance,$channel,$message){
        // 這里除了SUBSCRIBE、PSUBSCRIBE、UNSUBSCRIBE、PUNSUBSCRIBE這4條命令之外其它命令都不能使用
        var_dump($instance,$channel,$message);
    });
?>

留意我們接收消息的回調(diào)函數(shù)。除了SUBSCRIBEPSUBSCRIBE、UNSUBSCRIBEPUNSUBSCRIBE這4條命令以外,其它命令都不能使用。

如果你使用的是CLI(命令行界面)此處是有bug的,你可能無(wú)法退訂消息。只能通過(guò)組合鍵Ctrl+c結(jié)束退訂。

退訂頻道

使用UNSUBSCRIBE命令可以退訂某個(gè)或某些頻道。服務(wù)器將從pubsub_channels中解除客戶(hù)端與被退訂頻道之間的關(guān)聯(lián):

程序會(huì)根據(jù)被退訂頻道的名字、在pubsub_channels字典中找到頻道對(duì)應(yīng)的訂閱者鏈表,然后從訂閱者鏈表中刪除退訂客戶(hù)端的信息。

如果刪除了客戶(hù)端之后,頻道的訂閱者鏈表變成了空鏈表,那么說(shuō)明這個(gè)頻道已經(jīng)沒(méi)有任何的訂閱者了,程序?qū)?b>pubsub_channels字典中刪除頻道對(duì)應(yīng)的鍵。

訂閱模式

服務(wù)器將所有的訂閱關(guān)系都保存在服務(wù)器狀態(tài)的pubsub_channels屬性里面,在模式訂閱里服務(wù)器也將所有模式的訂閱關(guān)系都保存在服務(wù)器狀態(tài)的pubsub_patterns屬性里面。

struct redisServer {
    // ...
    // 保存所有模式訂閱關(guān)系
    list *pubsub_patterns;
    // ...
}

pubsub_patterns 屬性是一個(gè)鏈表,鏈表中的每個(gè)節(jié)點(diǎn)都包含著一個(gè)pubsubPattern結(jié)構(gòu),這個(gè)結(jié)構(gòu)的pattern屬性記錄了被訂閱的模式,而client屬性則記錄了訂閱模式的客戶(hù)端。

typedef struct pubsubPattern {
    // 訂閱模式的客戶(hù)端
    redisClient *client;
    // 被訂閱的模式
    robj * pattern;
} pubsubPattern;

每當(dāng)客戶(hù)端執(zhí)行PSUBSCRIBE命令訂閱某個(gè)或某些模式的時(shí)候,服務(wù)器會(huì)對(duì)每個(gè)被訂閱的模式執(zhí)行以下兩個(gè)操作:

新建一個(gè)pubsubPattern結(jié)構(gòu),將結(jié)構(gòu)的pattern屬性設(shè)置為被訂閱的模式(如:music.*),client 屬性設(shè)置為訂閱模式的客戶(hù)端。

pubsubPattern結(jié)構(gòu)添加到pubsub_patterns鏈表的表尾。

退訂模式

模式的退訂命令PUNSUBSCRIBEPSUBSCRIBE命令的反操作。當(dāng)一個(gè)客戶(hù)端退訂某個(gè)或某些模式的時(shí)候,服務(wù)器將在pubsub_patterns鏈表中查找并刪除那些pattern屬性為退訂模式并且client屬性為執(zhí)行退訂命令的客戶(hù)端的pubsubPattern結(jié)構(gòu)。

發(fā)送消息

redis客戶(hù)端執(zhí)行 PUBLISH 命令將消息發(fā)送給頻道的時(shí)候,服務(wù)器需要執(zhí)行以下兩個(gè)操作:

將消息發(fā)送給頻道的所有訂閱者。

如果有一個(gè)或多個(gè)模式與頻道相匹配。那么將消息發(fā)送給pattern模式的訂閱者。

第一個(gè)操作的偽代碼:

def channel_publish(channel,message):
/*
    如果channel鍵不存在pubsub_channels字典中
    那么說(shuō)明channel頻道沒(méi)有任何訂閱者
    程序不做發(fā)送動(dòng)作直接返回
*/
if channel not in server.pubsub_channels:
    return
    
/*
    運(yùn)行到這里,說(shuō)明channel頻道至少有一個(gè)訂閱者
    程序?qū)⒈闅vchannel頻道的訂閱者列表
    將消息發(fā)送給所有訂閱者
*/
for subscriber in server.pubsub_channels[channel]:
    send_message(subscriber,message)
    

第二個(gè)操作,因?yàn)榉?wù)器狀態(tài)中的pubsub_patterns鏈表記錄了所有模式的訂閱關(guān)系,所以為了將消息發(fā)送給所有與channel頻道相匹配的模式的訂閱者,PUBLISH命令要做的就是遍歷整個(gè)pubsub_patterns鏈表,查找那些模式相匹配的訂閱者。

def pattern_publish(channel,message):
    
    # 遍歷所有模式訂閱消息
    for pubsubPattern in server.pubsub_patterns:
        # 如果頻道和模式相匹配
        if(match(channel,pubsubPatter.pattern)):
            # 那么將消息發(fā)送給訂閱該模式的客戶(hù)端
                send_message(pubsubPattern.client,message)

最后PUBLISH命令可以用一下偽代碼來(lái)描述:

def publish(channel,message):
    # 將消息發(fā)送給channel頻道的所有訂閱者
    channel_publish(channel,message)
    
    #將消息發(fā)送給所有和channel 頻道相匹配的模式的訂閱者
    pattern_publish(channel,message)

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/23300.html

相關(guān)文章

  • Python--Redis實(shí)戰(zhàn):第三章:Redis命令:第六節(jié):發(fā)布訂閱

    摘要:上一篇文章實(shí)戰(zhàn)第三章命令第五節(jié)有序集合下一篇文章實(shí)戰(zhàn)第三章命令第七節(jié)其他命令一般來(lái)說(shuō),發(fā)布與訂閱又稱(chēng)的特點(diǎn)是訂閱者負(fù)責(zé)訂閱頻道,發(fā)送者負(fù)責(zé)向頻道發(fā)送二進(jìn)制字符串消息。到目前為止,本書(shū)介紹的大多數(shù)命令都是與特定數(shù)據(jù)類(lèi)型相關(guān)的。 上一篇文章:Python--Redis實(shí)戰(zhàn):第三章:Redis命令:第五節(jié):有序集合下一篇文章:Python--Redis實(shí)戰(zhàn):第三章:Redis命令:第七節(jié):其...

    DC_er 評(píng)論0 收藏0
  • python開(kāi)發(fā)-實(shí)現(xiàn)redis發(fā)布訂閱功能

    摘要:中的發(fā)布訂閱模型是一種消息通信模式,今天聊一下在中實(shí)現(xiàn)簡(jiǎn)單的發(fā)布訂閱功能。參考自鏈接描述以上就是發(fā)布訂閱的簡(jiǎn)單實(shí)現(xiàn),如有錯(cuò)誤,歡迎交流指正 redis中的發(fā)布/訂閱模型是一種消息通信模式,今天聊一下在python中實(shí)現(xiàn)簡(jiǎn)單的發(fā)布訂閱功能。 實(shí)現(xiàn)方式一: redis_helper.py: 封裝發(fā)布訂閱方法 import redis ...

    chengjianhua 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<