Redis发布与订阅

"发布/订阅"可以实现进程间的消息传递

发送者(发送信息的客户端)不是将信息直接发送给特定的接收者(接收信息的客户端), 而是将信息发送给频道(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 命令所发送的, 真正的信息。 信息的第二个元素是信息来源的频道, 而第三个元素则是信息的内容。

原文地址:https://www.cnblogs.com/yhq-qhh/p/9932625.html