Redis发布订阅(Pub/Sub)


概述

SUBSCRIBE,UNSUBSCRIBE和PUBLISH实现了发布/订阅消息传递,发送者不用编程就可以向特定的接受者发送消息(订阅者)。 发布的消息进入通道,不管有没有订阅。订阅者发表感兴趣的一个或多个通道,并且只接受他们感兴趣的消息,不管发布者是

不是存在。发布者和订阅者的去耦可以允许更大的伸缩性和更多动态的网络拓扑。

例如为了订阅通道foo和bar客户端发型一个SUBSCRIGE提供通道的名字。

SUBSCRIBE foo bar

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

客户端订阅一个或多个通道不应该发布命令,虽然它可以订阅或从其他通道退订。订阅和退订操作以消息的形式发送,所以客户端仅仅可以读取到一个表示消息类型元素的消息流。允许客户端订阅的命令是:SUBSCRIBE,PSUBSCRIBE,UNSUBSCRIBE,PUNSUBSCRIBE,PING和QUIT。

推送消息的格式

消息是有三个元素的数组。

第一个元素是消息类型:

  • subscribe:意思是我们成功的订阅了第二个元素指定的通道。第三个参数代表我们当前订阅的通道数量。
  • unsubscribe:意思是我们成功的退定了第二个元素指定的通道。第三个参数代表我们当前订阅的通道数量。最后一个参数是0时,表示我们不再订阅任何通道,并且客户端在发布/订阅状态之外可以发行各种Redis命令。
  • message:接收到由其他客户端发行PUBLISH命令推送的消息。第二个元素是始发通道,第三个参数是真实的消息。

数据库 & 生存空间

Pub/Sub没有相关的Key空间。在任何级别上不干扰,包括数据库数据。

在db10上发布,db1上的订阅者将会捕捉到。

如果你需要一些范围,通道用环境名字加前缀(test,staging,production)。

Wire协议实例

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发布/订阅实现支持模式匹配,客户端可以订阅全局样式的表达式以接收所有匹配的通道的消息。

例如:

PSUBSCRIBE news.*

将接收所有消息发送到通道new.art.figurative,news.music.jazz等等。所有全局表达式都有效,所以多个通配符也是支持的。

PUNSUBSCRIBE news.*

然后会从这些表达式退订客户端。通过这个调用将没有其他订阅影响。

接收到的消息以不同的格式发送:

  • 消息类型是pmessage:这是由其他客户端通过发行PUBLISH命令接收到的消息,匹配一个表达式匹配的订阅。第二个元素是原始模式匹配,第三个元素是原始通道名字,最后一个元素是真实的消息。

类似于SUBSCRIBE和UNSUBSCRIBE,PSUBSCRIBE和PUNSUBSCRIBE命令通过系统使用跟subscribe和unsubscribe消息格式一样的格式发送psubscribe和punsubscribe类型的消息确认消息。

消息匹配模式和通道订阅

客户端可以接受单个消息多次如果它的订阅多个模式匹配发布的消息,或者如果它同时订阅模式和通道匹配消息。就像下面的实例:

SUBSCRIBE foo
PSUBSCRIBE f*

在上面的实例,如果消息发送到foo通道,客户端将接收两个消息:一个类型是message,一个类型是pmessage。

模式匹配订阅时的意义

subscribe,unsubscribe,psubscribe和punsubscribe消息类型里,最后一个参数是订阅数。这是客户端匹配订阅的通道数量。所有客户端只有在退订通道和模式的结果数量为0的时候才退出Pub/Sub状态。

编程实例

Pieter Noordhuis提供了一个很棒的实例使用EventMachine和Redis创建一个多用户高性能的web聊天。

客户端类库实现提示

因为所有接收到的消息包含引起消息交付的原始订阅。客户端类库可以绑定原始订阅回调,使用hash表。

消息被接收时会执行一个lookup以便于投递消息到注册的回调。


原创文章,转载请注明出处:转载自Redis中文网 - Redis发布订阅(Pub/Sub)



最新文章

Redis最新文章

Redis最热文章