日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

      歡迎訪問 生活随笔!

      生活随笔

      當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

      编程问答

      redis——发布和订阅

      發布時間:2023/12/13 编程问答 28 豆豆
      生活随笔 收集整理的這篇文章主要介紹了 redis——发布和订阅 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

      頻道的訂閱和退訂

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

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

      struct redisServer {// ...// 保存所有頻道的訂閱關系dict *pubsub_channels;// ...};

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

      根據頻道是否已經有其他訂閱者, 關聯操作分為兩種情況執行:

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

      SUBSCRIBE?命令的實現可以用以下偽代碼來描述:

      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?中解除客戶端與被退訂頻道之間的關聯:

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

      UNSUBSCRIBE?命令的實現可以用以下偽代碼來描述:

      def unsubscribe(*all_input_channels):# 遍歷要退訂的所有頻道for channel in all_input_channels:# 在訂閱者鏈表中刪除退訂的客戶端server.pubsub_channels[channel].remove(client)# 如果頻道已經沒有任何訂閱者了(訂閱者鏈表為空)# 那么將頻道從字典中刪除if len(server.pubsub_channels[channel]) == 0:server.pubsub_channels.remove(channel)

      模式的訂閱和退訂

      前面說過,服務器將所有頻道的訂閱關系保存起來,與此類似,服務器也將所有模式的訂閱關系存在了pubsub_Patterns屬性里。

      struct redisServer {// ...// 保存所有頻道的訂閱關系list *pubsub_patterns;// ...};

      pubsub_Patterns屬性是一個鏈表,每個結點是被訂閱的模式,節點內記錄了模式,節點內的client屬性記錄了訂閱模式的客戶端。

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

      每當客戶端執行PSUBSCRIBE這個命令來訂閱某個或某些模式時,服務器會對每個被訂閱的模式執行下面的操作:

      1)新建一個pubsubPattern結構,設置好兩個屬性

      2)將新節點加到pubsub_patterns尾部

      偽代碼實現:

      def osubscribe(*all_input_patterns):#遍歷所有輸入的模式#記錄被訂閱的模式和對應的客戶端pubsubPattern=create()pubsubPattern.client=clientpubsubPattern.pattern=pattern#插入鏈表末尾server.pub_patterns.append(pubsubPattern)

      模式退訂命令PUNSUBSCRIBE是PSUBSCRIBE的反操作

      服務器將找到并刪除那些被退訂的模式

      偽代碼如下:(我想吐槽一下這樣時間復雜度。。。沒有更好的辦法嗎?)

      def osubscribe(*all_input_patterns):#遍歷所有退訂的模式for pattern in all_input_patterns:#遍歷每一個節點for pubsubPattern in server.pubsub_patterns:#如果客戶端和模式都相同if client==pubsubPattern.client:if pattern==pubsubPattern.pattern:#刪除server.pub_patterns.remove(pubsubPattern)

      發送消息

      當一個客戶端執行PUBLISH<channel> <message>命令將消息發送給頻道時,服務器需要:

      1)把消息發送給所有本頻道的訂閱者

      具體做法就是去pubsub_channels字典找到本頻道的鏈表,也就是訂閱名單,然后發消息

      2)將消息發給,包含本頻道的所有模式中的所有訂閱者

      具體做法就是去pubsub_patterns查找包含本頻道的模式,并且把消息發送給訂閱它們的客戶端。

      查看訂閱信息

      redis2.8新增三個命令,用來查看頻道和模式的相關信息。

      PUBLISH CHANNELS[pattern]用于返回服務器當前被訂閱的頻道,pattern可寫可不寫,不寫就查看所有,否則查看與pattern匹配的對應頻道

      這個子命令是通過遍歷pubsub_channels字典實現的。

      PUBLISH NUMSUB[CHANNEL-1 CHANNEL-2.....]返回這些頻道的訂閱者數量

      這個子命令是通過遍歷pubsub_channels字典,查看對應鏈表長度實現的。

      PUBLISH NUMPAT返回被訂閱模式數量

      這個子命令是通過返回pubsub_patterns的長度實現的。

      總而言之,PUBSUB?命令的三個子命令都是通過讀取?pubsub_channels?字典和?pubsub_patterns?鏈表中的信息來實現的。

      總結

      以上是生活随笔為你收集整理的redis——发布和订阅的全部內容,希望文章能夠幫你解決所遇到的問題。

      如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。