相关的发布/订阅命令
- PSUBSCRIBE
- PUBLISH
- PUBSUB
- PUNSUBSCRIBE
- SUBSCRIBE
- UNSUBSCRIBE
前言
SUBSCRIBE、UNSUBSCRIBE 和 PUBLISH 实现了发布/订阅消息传递规范。发布者将发布的消息发布到对应的通道中,而不知道有哪些订阅者。订阅者对一个或多个通道感兴趣,并且只接收感兴趣的消息,而不知道有哪些发布者。发布/订阅的解耦可以实现更大的可扩展性和更复杂的网络拓扑结构。
举例:
客户端通过SUBSCRIBE订阅foo和bar两个通道。
SUBSCRIBE foo bar
其他客户端发送到这两个通道的消息将被redis推送给所有订阅了这两个通道的客户端
订阅一个或多个通道的客户端不应发出命令,尽管它可以订阅和取消订阅其他通道。订阅和取消订阅操作的响应是以消息的形式发送,这样客户端就可以读取一个连贯的消息流,其中第一个元素指示消息的类型。 订阅客户端上下文中允许的命令是 SUBSCRIBE、PSUBSCRIBE、UNSUBSCRIBE、PUNSUBSCRIBE、PING 和 QUIT。
注意:redis-cli 一旦进入订阅模式就不会接受任何命令,只能使用 Ctrl-C 退出该模式。
一、推送消息的格式
消息是包含三个元素的数组响应
SUBSCRIBE foo bar
第一个元素是消息类型:
- subscribe: 意味着我们成功订阅了作为响应中第二个元素给出的通道。 第三个参数代表我们当前订阅的通道数量。
- unsubscribe::意味着我们成功取消订阅作为响应中第二个元素给出的通道。 第三个参数代表我们当前订阅的通道数量。 当最后一个参数为零时,我们不再订阅任何通道,客户端可以发出任何类型的 Redis 命令,因为我们不再处于 Pub/Sub 状态。
- message:它是由于另一个客户端发出的PUBLISH命令而收到的消息。 第二个元素是发起通道的名称,第三个参数是实际的消息负载。
二、Database & Scoping
Pub/Sub 与键空间无关。 它不会在任何级别上干扰它,包括数据库编号。
在 db10上发布,将被 db 1 上的订阅者接收到。
如果您需要某种类型的范围,使用环境名称(测试、预发、生产等)为通道添加前缀。
三、Wire protocol example
SUBSCRIBE first second
*3
$9
subscribe
$5
first
:1
*3
$9
subscribe
$6
second
:2
此时,我们从另一个客户端对名为 second 的通道发出 PUBLISH 命令:
此时订阅的客户端就会收到消息
现在客户端使用不带附加参数的 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.*
由于模式匹配而收到的消息以不同的格式发送:
消息的类型是pmessage:它是作为另一个客户端发出的 PUBLISH 命令的结果接收到的消息,匹配模式匹配订阅。 第二个元素是匹配的原始模式,第三个元素是发起通道的名称,最后一个元素是实际的消息负载。
四、模式匹配订阅
如果客户端订阅了多个与已发布消息匹配的模式,或者订阅了与该消息匹配的模式和通道,则该客户端可能会多次收到一条消息。 如下例所示:
SUBSCRIBE foo
PSUBSCRIBE f*
在上面的例子中,如果一条消息被发送到通道 foo,客户端将收到两条消息:一条是 message 类型,一条是 pmessage 类型。
五、模式匹配订阅计数的含义
在 subscribe、unsubscribe、psubscribe 和 punsubscribe 消息类型中,最后一个参数是仍处于活动状态的订阅数。 这个数字实际上是客户端仍然订阅的频道和模式的总数。 因此,只有当由于取消订阅所有通道和模式而导致此计数下降到零时,客户端才会退出 Pub/Sub 状态。
六、编程示例
a multi user high performance web chat
七、编程示例
因为所有收到的消息都包含导致消息传递的原始订阅(消息类型的情况下是通道,pmessage 类型的情况下是原始模式)客户端库可能会将原始订阅绑定到回调(可以是匿名函数, 块、函数指针),使用哈希表。
当收到消息时,可以进行 O(1) 查找,以便将消息传递给注册的回调。