SUBSCRIBE, UNSUBSCRIBE和PUBLISH实现了Publish/Subscribe的消息发送范例, 发布者不需要做程序处理就能发送消息到特定的订阅者. 发布者只需要将消息发送到channel中, 而不知道是哪个订阅者订阅了它. 订阅者向服务器表达自己感兴趣的一个或多个channel, 只接收它们感兴趣的消息, 而不知道是那一个发布者发布的消息. 这样实现了发布和订阅的解耦可以允许系统是可扩展的和可增加更多的网络拓扑.
下面作为一个实例, 为了订阅通道foo和bar, 客户端运用SUBSCRIBE命令
SUBSCRIBE foo bar
如果有该类型的消息通道被其他客户端发了, 那么就会推送到所有的订阅客户端.
一个客户端如果已经订阅了一个或多个通道, 那么就不应该再发出其他命令, 虽然它还可以订阅和取消订阅通道. SUBSCRIBE和UNSUBSCRIBE命令操作的回复被一种固定的消息格式发送, 所以客户端能够读取连续的消息流, 它的第一个元素标识了消息的类型.
发布消息格式
消息是一个有三个元素的应答数组
第一个元素是消息的类型
- subscribe: 意思是我们成功订阅到第二个元素代表的通道( 消息类型 ). 第三个元素代表我们当前已经订阅的通道数量.
- unsubscribe: 意思是我们成功取消订阅第二个元素代表的通道( 消息类型 ). 第三个元素代表我们当前已经订阅的通道数量. 当最后一个元素是0, 我们将不再订阅任何通道, 以及客户端可以发送任意类型的redis命令, 因为我们以及不在pub/sub状态.
- message: 这是一个接收其他客户端调用PUBLISH命令发布的消息. 第二个元素是订阅的通道名称, 第三个元素表示真实的消息内容.
报文协议示例
SUBSCRIBE first second
*3
\$9
subscribe
\$5
first
:1
*3
\$9
subscribe
\$6
second
:2
此时, 从另一个客户端发布second通道
PUBLISH second Hello
这是订阅了second通道的客户端接收到的报文内容
*3
\$7
message
\$6
second
\$5
Hello
现在客户端使用UNSUBSCRIBE命令取消订阅所有通道
*3
\$11
unsubscribe
\$6
second
:1
*3
\$11
unsubscribe
\$5
first
:0
模式匹配订阅
redis pub/sub 支持模式匹配订阅. 客户端可以订阅全局类型的模式以便获取所有匹配到的通道.
例如:
PSUBSCRIBE news.*
这样的话, 这个客户端将收到如 news.art.figurative, news.music.jazz 等等相匹配的通道信息.
PUNSUBSCRIBE news.*
这样的话, 这个客户端将取消匹配这个模式的所有通道订阅.
模式匹配接收到的消息以不同的形式传输发送:
* 这个消息类型是pmessage: 它是其他客户端调用PUBLIST命令发布的消息, 第2个元素是模式匹配, 第3个元素是匹配到的通道名, 最后一个元素是真真正的消息内容.
消息同时匹配模式订阅和具体的通道订阅
一个客户端有可能接收多次同一个消息, 如果这个订阅信息匹配到多个模式订阅, 或者被订阅到模式匹配和具体的通道. 像下面的例子:
SUBSCRIBE foo
PSUBSCRIBE f*