《Redis官方文档》发布和订阅

原文链接

发布/订阅(Pub/Sub)

SUBSCRIBE、UNSUBSCRIBE 和 PUBLISH 这三个命令实现了发布/订阅消息模式(引用自维基百科),发送者(发布者)并不是直接发送它们的消息给指定的接收者(订阅者),而是将消息发布到特定的消息通道,并且不需要知道订阅者(如果有的话)的任何信息。订阅者可以订阅一个或多个感兴趣的消息通道,同时也只会收到他们感兴趣通道的信息,而不用去关心是谁发布的。这种发布者与订阅者的解耦,使其具备更强的扩展性并得到一个更加动态的网络拓扑。


例如为了订阅通道foo和bar,客户端可以使用通道名称为参数去调用 SUBSCRIBE 命令:

SUBSCRIBE foo bar

其他客户端发送到消息到这些通道时,消息会由 Redis 推送到所有订阅了这些通道的客户端。

订阅了一个或多个通道的客户端就不应该再使用命令,尽管它还能订阅其他频道或取消订阅其他通道。订阅和取消订阅的执行结果会以消息的形式返回。所以客户端能够解析这互相耦合的消息,其中第一个元素表示消息的类型。订阅了通道的客户端上允许使用的命令有 SUBSCRIBE、PSUBSCRIBE、UNSUBSCRIBE、PUNSUBSCRIBE、PING和QUIT。

推送消息的格式

消息是一条含有三个元素的@array-reply。第一个元素是消息的类型:

  • subscribe:意味着我们已经成功订阅了第二个元素所指的通道。第三个参数表示当前已经订阅的通道总数。
  • unsubscribe:意味着已经成功的取消了第二个元素所指的通道。第三个参数表示当前订阅的频道总数。当最后一个参数是 0 的时候,就表示不再订阅任何频道,同时客户端也可以使用Redis提供的任何命令,因为此时客户端已经退出发布/订阅状态。
  • message:这是某一个客户端使用 PUBLISH 命令后会收到的操作结果信息。第二个元素是信息来源的频道,同时第三个参数是真实消息的内容。

数据库与范围

Pub/Sub 模式与 KEY 空间无关。它与任何层面无关,包括数据库数目。
在 db 10 上进行发布,db 1上的订阅者也会收到信息。
如果你需要覆盖某一些类型,把频道的前缀用一些特定的变量(test,staging,production….)
例如:

SUBSCRIBE first second
*3
$9
subscribe
$5
first
:1
*3
$9
subscribe
$6
second
:2

此时,从另一个客户端上对 second 频道执行 PUBLISH 命令操作:

PUBLISH second Hello

这就是前面订阅了频道的客户端收到的信息:

*3
$7
message
$6
second
$5
Hello

现在客户端执行无参的 UNSUBSCRIBE 命令来取消自己订阅的所有频道:

UNSUBSCRIBE
*3
$11
unsubscribe
$6
second
:1
*3
$11
unsubscribe
$5
first
:0

订阅的模式匹配

Redis 的 Pub/Sub 实现支持模式匹配。客户端可以用 glob 风格的模式去接收频道名称与模式相匹配的所有频道消息。
例如:执行命令PSUBSCRIBE news.*的客户端将后收到所有发送到 news.art.figurative,news.music.jazz 等等频道的信息。所有 glob 风格的模式匹配都是有效的,同时也支持多重通配符。
执行命令PUNSUBSCRIBE news.*的客户端会取消订阅频道名称与 给定模式(news.*) 相匹配的所有频道,而其他已经订阅的频道不会爱影响。模式匹配订阅的信息格式是另一种不同的格式:
消息的类型是 pmessage:表示另一个客户端执行 PUBLISH 命令向频道发送消息,而频道符合当前客户端订阅的模式匹配。第二个元素就是匹配的模式,第三个元素就是模式匹配到的频道名称,最后一个元素就是真正的消息载体。
与系统处理 SUBSCRIBE 和 UNSUBSCRIBE, PSUBSCRIBE 和 PUNSUBSCRIBE 命令一样,发送的消息类型为 psubscribe 和 punsubscribe ,然后使用 subscribe 和 unsubscribe 一样的消息格式。

消息同时匹配模式与订阅的频道

一个客户端可能多次收到同一条消息,如果它订阅的多个模式匹配到了一条发布的消息,或者它订阅的模式与频道匹配到了同一条消息。例如:

SUBSCRIBE foo
PSUBSCRIBE f*

在上面的例子中,如果一条消息发送到foo频道,客户端将会收到两条消息。一个是 message类型的消息,一种是pmessage类型的消息。

模式匹配下订阅数的意义

在 subscribe, unsubscribe, psubscribe 和 punsubscribe 等消息类型中,最后一个参数表示仍在订阅的频道数。这个数字实际上就是客户端订阅的频道与模式的总数。
所以当客户端取消订阅所有频道和模式时,也就是这个总数值变为 0 时,客户端将会退出 Pub/Sub 模式。

编程示例

Pieter Noordhuis 提供了一个很好的例子,通过 EventMachine 和 Redis创建了一个多用户高性能的WEB聊天网站

户端库实现提示

由于所有的消息都会有一个订阅源。(当消息类型为 message 时,订阅源是一个频道,当消息类型为 pmessage 时,订阅源是一个模式)客户端可以利用一个HASH表将这些订阅源与回调函数绑定起来,这样当一个消息被接收后,能在 O(1) 的时间内将消息交给注册好的回调函数。

原创文章,作者:kepupublish,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/114826.html

(0)
上一篇 2021年8月27日 11:42
下一篇 2021年8月27日 11:42

相关推荐

发表回复

登录后才能评论