Redis - 發布/訂閱模式

來源:互聯網
上載者:User

標籤:

Redis 提供了一組命令可以讓開發人員實現 “發布/訂閱” 模式。“發布/訂閱” 可以實現進程間的訊息傳遞,其原理是這樣的:

“發布/訂閱” 模式中包含兩種角色,分別是發行者和訂閱者。訂閱者可以訂閱一個或若干個頻道(channel),而發行者可以向指定的頻道發送訊息,所有訂閱此頻道的訂閱者都會收到此訊息。

發行者發布訊息的命令是 PUBLISH,用法是 PUBLISH channel message,如向 channel.1 說一聲 “hi”:

redis> PUBLISH channel.1 hi(integer) 0

這樣訊息就發出去了。PUBLISH 命令的傳回值表示接收到這條訊息的訂閱者數量。因為此時沒有客訂閱 channel.1,所以返回 0。發出去的訊息不會被持久化,也就是說當有客訂閱 channel.1 後只能收到後續發布到該頻道的訊息,之前發送的就收不到了。

訂閱頻道的命令是 SUBSCRIBE,可以同時訂閱多個頻道,用法是 SUBSCRIBE channel [channel ...]。現在新開一個 redis-cli 執行個體 A,用它來訂閱 channel.1:

redis A> SUBSCRIBE channel.1Reading messages... (press Ctrl-C to quit)1) "subscribe"2) "channel.1"3) (integer) 1

執行 SUBSCRIBE 命令後用戶端會進入訂閱狀態,處於此狀態下用戶端不能使用除 SUBSCRIBE、UNSUBSCRIBE、PSUBSCRIBE 和 PUNSUBSCRIBE 這 4 個屬於 “發布/訂閱” 模式的命令之外的命令,否則會報錯。

進入訂閱狀態後用戶端可能收到 3 種類型的回複。每種類型的回複都包含 3 個值,第一個值是訊息的類型,根據訊息類型不同,第二、三個值的含義也不同。訊息類型可能的取值有以下 3 個。

(1)subscribe。表示訂閱成功的反饋資訊。第二個值是訂閱成功的頻道名稱,第三個值是當前客訂閱的頻道數量。

(2)message。表示接收到的訊息。第二個值表示產生訊息的頻道名稱,第三個值是訊息的內容。

(3)unsubscribe。表示成功取消訂閱某個頻道。第二個值是對應的頻道名稱,第三個值是當前客訂閱的頻道數量,當次值為 0 時用戶端會退出訂閱狀態,之後就可以執行其他非 “發布/訂閱” 模式的命令了。

上例中當執行個體 A 訂閱了 channel.1 進入訂閱狀態後收到了一條 subscribe 類型的回複,這時我們開啟另一 redis-cli 執行個體 B,並向 channel.1 發送一條訊息:

redis B> PUBLISH channel.1 hi!(integer) 1

傳回值為 1,表示有一個客訂閱了 channel.1,此時執行個體 A 收到了類型為 message 的回複:

1) "message"2) "channel.1"3) "hi!"

使用 UNSUBSCRIBE 命令可以取消指定的頻道,用法為 UNSUBSCRIBE [channel [channel ...]],如果不指定頻道則會取消訂閱所有頻道。由於 redis-cli 的限制,無法在其中測試 UNSUBSCRIBE 命令。

 

按照規則訂閱

除了可以使用 SUBSCRIBE 命令訂閱指定名稱的頻道外,還可以使用 PSUBSCRIBE 命令訂閱指定的規則。規則支援 glob 風格萬用字元格式,下面新開啟一個 redis-cli 執行個體 C 進行示範:

redis C> PSUBSCRIBE channel.?*Reading messages... (press Ctrl-C to quit)1) "psubscribe"2) "channel.?*"3) (integer) 1

規則 channel.?* 可以匹配 channel.1 和 channel.10,但不會匹配 channel1.。這時在執行個體 B 中發布訊息:

127.0.0.1:6379> PUBLISH channel.1 hi!(integer) 2

返回結果為 2 是因為執行個體 A 和執行個體 C 兩個用戶端都訂閱了 channel.1 頻道。執行個體 C 接收到的回複是:

1) "pmessage"2) "channel.?*"3) "channel.1"4) "hi!"

第一個值表示這條訊息是通過 PSUBSCRIBE 命令訂閱頻道而收到的,第二個值表示訂閱時使用的萬用字元,第三個值表示實際收到訊息的頻道命令,第三個值則是訊息內容。

使用 PSUBSCRIBE 命令可以重複訂閱一個頻道,如某用戶端執行 PSUBSCRIBE channel.? channel.?*,這時想 channel.2 發布訊息後該用戶端會收到兩條訊息,而同時 PUBLISH 命令返回的值也是 2 而不是 1。同樣的,如果有另一用戶端執行了 SUBSCRIBE channel 10 和 PSUBSCRIBE channel.?* 的話,向 channel.10 發送命令該用戶端也會收到兩條訊息(但是是兩種類型:message 和 pmessage),同時 PUBLISH 命令會返回 2。

PUNSUBSCRIBE 命令可以退訂指定的規則,用法是 PUNSUBSCRIBE [pattern [pattern ...]],如果沒有參數則會退訂所有規則。

使用 PUNSUBSCRIBE 命令只能退訂通過 PSUBSCRIBE 命令訂閱的規則,不會影響直接通過 SUBSCRIBE 命令訂閱的頻道;同樣 UNSUBSCRIBE 命令也不會影響通過 PSUBSCRIBE 命令訂閱的規則。另外容易出錯的一點是使用 PUNSUBSCRIBE 命令退訂某個規則時不會將其中的萬用字元展開,而是進行嚴格的字串匹配,所以 PUNSUBSCRIBE * 無法退訂 channel.* 規則,而是必須使用 PUNSUBSCRIBE channel.* 才能退訂。

 

Redis - 發布/訂閱模式

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.