Redis 发布/订阅

SUBSCRIBE, UNSBUSCRIBE和PUBLISH实现了发布/订阅消息范型。关于这个范型,在Wikipedia上的解释是发送者(发布者)没有程序化地指定他们消息的具体接收者(订阅者)。 发布的消息根据特征放入到对应的通道,并且无须知道订阅者是谁。订阅者可以对一个或者多个通道的表示感兴趣,并且仅接收感兴趣的消息,而无须知道发布者是谁。发布者和订阅者解耦有利于扩展性和动态网络拓扑。

例如,为了订阅通道foo和bar,客户端发送了一个SUBSCRIBE命令,并带上通道的名称:
SUBSCRIBE foo bar
其他客户端发送到这些通道的消息将会被Redis推送到那些订阅了消息的客户端。

已经订阅了一个或者多个通道的客户端不应该再发送命令,不过它能够对通道进行订阅和解除订阅。对SUBSCRIBE和UNSUBSCRIBE操作,客户端将会收到一个消息。 消息的第一个元素指定了消息类型, 所以客户端能够仅读取 相关联的 消息 流。

推送消息的格式

消息是一个带有三个元素的数组

第一个元素是消息的类型:
  • subscribe: 指的是我们成功对通道进行了订阅。第二个元素会给出成功订阅的通道名称。第三个元素表示我们当前订阅的通道数量。
  • unsubscribe: 指的是我们成功对通道解除了订阅。第二个元素会给出成功解除订阅的通道名称。第三个参数表示我们已经订阅的通道数量。当最后一个参数为0,就表示我们不再订阅任何通道。这时客户端能够发送任何类型的Redis命令,因为我们已经不在Pub/Sub状态中。
  • message: 当其它客户端发送PUBLISH命令时,就会接收到这样的消息。第二个元素是来源通道名称。第三个参数是具体的消息体。

Database & Scoping


Pub/Sub和key空间无关。它被设计成和它在哪一个层(包括数据库编号)无关。

在db 10上发布,也会被在db 1上的订阅者听到。

如果你需要某种scope, 可以给通道加上环境名称的前缀(测试,预发,生产等等)。

Wire protocol example

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
现在这个客户端使用不带额外参数的UNSUSCRIBE命令 对所有通道解除订阅:
UNSUBSCRIBE
*3
$11
unsubscribe
$6
second
:1
*3
$11
unsubscribe
$5
first
:0
模式匹配订阅

Redis Pub/Sub实现支持模式匹配. 客户端可以对glob-style模式进行订阅。这样就可以接收所有发送到匹配指定模式通道的消息。

例如
PSUBSCRIBE news.*
将会收到所有发送到如 news.art.figurativenews.music.jazzd这样通道等的 消息。所有的glob-style模式都是有效的,所以也支持multiple通配符。
PUNSUBSCRIBE news.*
解除对这个模式的订阅,其它的订阅将不会受到影响。

通过模式匹配接收的消息使用不同的格式进行发送
  • 消息的类型是pmessage: 当另外一个客户端发送PUBLISH命令,符合模式匹配订阅的客户端就回收到这样的消息。第二个元素是匹配上的最初模式,第三个元素是原始通道的名称,最后一个元素是消息内容。
和SUBSCRIBE和UNSUBSCRIBE类似,系统发送类型为psubscribe和punsubscribe的消息来确实 PSUBSCRIBE和PUNSBUSCRIBE命令, 并且消息格式与subscribe和unsubscribe一样。

模式和通道订阅都匹配的消息

如果客户端订阅了匹配同一条消息的多个模式,或者是同时订阅了匹配同一条消息的模式和通道,那么客户端就可能接收这个消息多次,如下面的例子:
SUBSCRIBE foo
PSUBSCRIBE f*
在上面例子,如果一个消息被发送到foo通道,客户端将会接收两条消息: 一个message类型和一个pmessage类型。

模式匹配的订阅计数含义

在subscibe, unsubscribe, psubscribe和punsubscribe消息类型中,最后一个参数是有效的订阅计数。这个数字事实上是客户端依然订阅的通道和模式的总数。所以只有当对所有通道和模式解除订阅,使得计数降到0,客户端才可以退出Pub/Sub状态。

编程例子

Pieter Noordhuis提供一个使用EventMachine和Redis实现的多用户高性能web聊天实例。

客户端库实现提示

因为所有接收到的消息都包含最初订阅信息(message类型下的通道名称,或者pmessage类型下的模式)。所以消息传递客户端库可以使用hash表将最初订阅信息绑定到回调函数上(可以是匿名函数、语句块和函数指针)。

当接收到一个消息时,只需要O(1)的查询复杂度,就可以找到注册的回调函数。之后就可以将消息传递给这个回调函数。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值