"发布/订阅"可以实现进程间的消息传递
发送者(发送信息的客户端)不是将信息直接发送给特定的接收者(接收信息的客户端), 而是将信息发送给频道(channel), 然后由频道将信息转发给所有对这个频道感兴趣的订阅者。
发送者无须知道任何关于订阅者的信息, 而订阅者也无须知道是那个客户端给它发送信息, 它只要关注自己感兴趣的频道即可。
发布者(publisher) :发送消息的客户端。
订阅者(subscriber) :通过订阅频道获取消息的客户端,每个频道都可以有任意多个订阅者。
频道(channel) : 负责接收发布者发送的消息,并将消息转发给订阅者。
发布的消息不会持久化,只能收到订阅后的消息,执行subscribe命令后客户端会进入"订阅"状态,处于此状态下的客户端不能使用除 subscribe、unsubscribe、psubscribe和punsubscribe这4个属于"发布/订阅"模式命令之外的命令,否则会报错
发布和订阅命令
127.0.0.1:6379> publish news-sing tmm #发布命令
(integer) 0 #订阅者数量
127.0.0.1:6379> subscribe news-sing #订阅命令
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "news-sing"
3) (integer) 1
再次发布
127.0.0.1:6379> publish news-sing wk
(integer) 1
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "news-sing"
3) (integer) 1
1) "message"
2) "news-sing"
3) "wk"
订阅模式
127.0.0.1:6379> psubscribe news* yl* #匹配所有已news和yl开头的频道 Reading messages... (press Ctrl-C to quit) 1) "psubscribe" #返回值的类型:显示订阅成功 2) "news*" #订阅的模式 3) (integer) 1 #目前已订阅的模式数量 1) "psubscribe" 2) "yl*" 3) (integer) 2
1) "pmessage" #返回值的类型:信息
2) "news*" #信息匹配的模式
3) "news-play" #信息本身的目标频道
4) "lq" #信息的内容
取消订阅
127.0.0.1:6379> unsubscribe news-sing #unsubscribe 不加参数表示退订所有频道
1) "unsubscribe"
2) "news-sing"
3) (integer) 0
退订指定模式
127.0.0.1:6379> punsubscribe new*
1) "punsubscribe"
2) "new*"
3) (integer) 0
pubsub 查看订阅与发布系统状态的内省命令
1)pubsub channels [pattern] : 列出当前活跃的频道(至少有一个订阅者的频道)
-
如果不给出 pattern 参数,那么列出订阅与发布系统中的所有活跃频道。
-
如果给出 pattern 参数,那么只列出和给定模式 pattern 相匹配的那些活跃频道。
# client-1 订阅 news.it 和 news.sport 两个频道
client-1> SUBSCRIBE news.it news.sport
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "news.it"
3) (integer) 1
1) "subscribe"
2) "news.sport"
3) (integer) 2
client-2 订阅 news.it 和 news.internet 两个频道
client-2> SUBSCRIBE news.it news.internet
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "news.it"
3) (integer) 1
1) "subscribe"
2) "news.internet"
3) (integer) 2
首先, client-3 打印所有活跃频道
注意,即使一个频道有多个订阅者,它也只输出一次,比如 news.it
client-3> PUBSUB CHANNELS
1) "news.sport"
2) "news.internet"
3) "news.it"
接下来, client-3 打印那些与模式 news.i* 相匹配的活跃频道
因为 news.sport 不匹配 news.i* ,所以它没有被打印
redis> PUBSUB CHANNELS news.i*
1) "news.internet"
2) "news.it"
2) pubsub numsub [channel-1 ...] : 返回给定频道的订阅者数,订阅模式的客户端不计算在内
# client-1 订阅 news.it 和 news.sport 两个频道
client-1> SUBSCRIBE news.it news.sport
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "news.it"
3) (integer) 1
1) "subscribe"
2) "news.sport"
3) (integer) 2
client-2 订阅 news.it 和 news.internet 两个频道
client-2> SUBSCRIBE news.it news.internet
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "news.it"
3) (integer) 1
1) "subscribe"
2) "news.internet"
3) (integer) 2
client-3 打印各个频道的订阅者数量
client-3> PUBSUB NUMSUB news.it news.internet news.sport news.music
1) "news.it" # 频道
2) "2" # 订阅该频道的客户端数量
3) "news.internet"
4) "1"
5) "news.sport"
6) "1"
7) "news.music" # 没有任何订阅者
8) "0"
3) pubsub numpat : 返回订阅模式的数量 #注意, 这个命令返回的不是订阅模式的客户端的数量, 而是客户端订阅的所有模式的数量总和
# client-1 订阅 news.* 和 discount.* 两个模式
client-1> PSUBSCRIBE news.* discount.
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "news."
3) (integer) 1
1) "psubscribe"
2) "discount.*"
3) (integer) 2
client-2 订阅 tweet.* 一个模式
client-2> PSUBSCRIBE tweet.
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "tweet."
3) (integer) 1
client-3 返回当前订阅模式的数量为 3
client-3> PUBSUB NUMPAT
(integer) 3
注意,当有多个客户端订阅相同的模式时,相同的订阅也被计算在 PUBSUB NUMPAT 之内
比如说,再新建一个客户端 client-4 ,让它也订阅 news.* 频道
client-4> PSUBSCRIBE news.
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "news."
3) (integer) 1
这时再计算被订阅模式的数量,就会得到数量为 4
client-3> PUBSUB NUMPAT
(integer) 4
信息格式
频道转发的每条信息都是一条带有三个元素的多条批量回复(multi-bulk reply)。
-
subscribe : 表示当前客户端成功地订阅了信息第二个元素所指示的频道。 而信息的第三个元素则记录了目前客户端已订阅频道的总数。
-
unsubscribe : 表示当前客户端成功地退订了信息第二个元素所指示的频道。 信息的第三个元素记录了客户端目前仍在订阅的频道数量。 当客户端订阅的频道数量降为 0 时, 客户端不再订阅任何频道, 它可以像往常一样, 执行任何 Redis 命令。
-
message : 表示这条信息是由某个客户端执行 PUBLISH 命令所发送的, 真正的信息。 信息的第二个元素是信息来源的频道, 而第三个元素则是信息的内容。