99re热这里只有精品视频,7777色鬼xxxx欧美色妇,国产成人精品一区二三区在线观看,内射爽无广熟女亚洲,精品人妻av一区二区三区

Redis 頻道的訂閱與退訂

2018-08-02 14:56 更新

當一個客戶端執(zhí)行 SUBSCRIBE 命令, 訂閱某個或某些頻道的時候, 這個客戶端與被訂閱頻道之間就建立起了一種訂閱關系。

Redis 將所有頻道的訂閱關系都保存在服務器狀態(tài)的 pubsub_channels 字典里面, 這個字典的鍵是某個被訂閱的頻道, 而鍵的值則是一個鏈表, 鏈表里面記錄了所有訂閱這個頻道的客戶端:

struct redisServer {

    // ...

    // 保存所有頻道的訂閱關系
    dict *pubsub_channels;

    // ...

};

比如說, 圖 IMAGE_PUBSUB_CHANNELS 就展示了一個 pubsub_channels 字典示例, 這個字典記錄了以下信息:

  • client-1 、 client-2 、 client-3 三個客戶端正在訂閱 "news.it" 頻道。
  • 客戶端 client-4 正在訂閱 "news.sport" 頻道。
  • client-5 和 client-6 兩個客戶端正在訂閱 "news.business" 頻道。

訂閱頻道

每當客戶端執(zhí)行 SUBSCRIBE 命令, 訂閱某個或某些頻道的時候, 服務器都會將客戶端與被訂閱的頻道在 pubsub_channels 字典中進行關聯(lián)。

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

  • 如果頻道已經(jīng)有其他訂閱者, 那么它在 pubsub_channels 字典中必然有相應的訂閱者鏈表, 程序唯一要做的就是將客戶端添加到訂閱者鏈表的末尾。
  • 如果頻道還未有任何訂閱者, 那么它必然不存在于 pubsub_channels 字典, 程序首先要在 pubsub_channels 字典中為頻道創(chuàng)建一個鍵, 并將這個鍵的值設置為空鏈表, 然后再將客戶端添加到鏈表, 成為鏈表的第一個元素。

舉個例子, 假設服務器 pubsub_channels 字典的當前狀態(tài)如圖 IMAGE_PUBSUB_CHANNELS 所示, 那么當客戶端 client-10086 執(zhí)行命令:

SUBSCRIBE "news.sport" "news.movie"

之后, pubsub_channels 字典將更新至圖 IMAGE_AFTER_SUBSCRIBE 所示的狀態(tài), 其中用虛線包圍的是新添加的節(jié)點:

  • 更新后的 pubsub_channels 字典新增了 "news.movie" 鍵, 該鍵對應的鏈表值只包含一個 client-10086 節(jié)點, 表示目前只有 client-10086一個客戶端在訂閱 "news.movie" 頻道。
  • 至于原本就已經(jīng)有客戶端在訂閱的 "news.sport" 頻道, client-10086 的節(jié)點放在了頻道對應鏈表的末尾, 排在 client-4 節(jié)點的后面。

SUBSCRIBE 命令的實現(xiàn)可以用以下偽代碼來描述:

def subscribe(*all_input_channels):

    # 遍歷輸入的所有頻道
    for channel in all_input_channels:

        # 如果 channel 不存在于 pubsub_channels 字典(沒有任何訂閱者)
        # 那么在字典中添加 channel 鍵,并設置它的值為空鏈表
        if channel not in server.pubsub_channels:
            server.pubsub_channels[channel] = []

        # 將訂閱者添加到頻道所對應的鏈表的末尾
        server.pubsub_channels[channel].append(client)

退訂頻道

UNSUBSCRIBE 命令的行為和 SUBSCRIBE 命令的行為正好相反 —— 當一個客戶端退訂某個或某些頻道的時候, 服務器將從 pubsub_channels 中解除客戶端與被退訂頻道之間的關聯(lián):

  • 程序會根據(jù)被退訂頻道的名字, 在 pubsub_channels 字典中找到頻道對應的訂閱者鏈表, 然后從訂閱者鏈表中刪除退訂客戶端的信息。
  • 如果刪除退訂客戶端之后, 頻道的訂閱者鏈表變成了空鏈表, 那么說明這個頻道已經(jīng)沒有任何訂閱者了, 程序?qū)?nbsp;pubsub_channels 字典中刪除頻道對應的鍵。

舉個例子, 假設 pubsub_channels 的當前狀態(tài)如圖 IMAGE_BEFORE_UNSUBSCRIBE 所示, 那么當客戶端 client-10086 執(zhí)行命令:

UNSUBSCRIBE "news.sport" "news.movie"

之后, 圖中用虛線包圍的兩個節(jié)點將被刪除, 如圖 IMAGE_AFTER_UNSUBSCRIBE 所示:

  • 在 pubsub_channels 字典更新之后, client-10086 的信息已經(jīng)從 "news.sport" 頻道和 "news.movie" 頻道的訂閱者鏈表中被刪除了。
  • 另外, 因為刪除 client-10086 之后, 頻道 "news.movie" 已經(jīng)沒有任何訂閱者, 因此鍵 "news.movie" 也從字典中被刪除了。

UNSUBSCRIBE 命令的實現(xiàn)可以用以下偽代碼來描述:

def unsubscribe(*all_input_channels):

    # 遍歷要退訂的所有頻道
    for channel in all_input_channels:

        # 在訂閱者鏈表中刪除退訂的客戶端
        server.pubsub_channels[channel].remove(client)

        # 如果頻道已經(jīng)沒有任何訂閱者了(訂閱者鏈表為空)
        # 那么將頻道從字典中刪除
        if len(server.pubsub_channels[channel]) == 0:
            server.pubsub_channels.remove(channel)
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號