《Redis官方文档》发布和订阅

    xiaoxiao2024-04-09  123

    发布/订阅(Pub/Sub)

    SUBSCRIBE、UNSUBSCRIBE 和 PUBLISH 这三个命令实现了发布/订阅消息模式(引用自维基百科),发送者(发布者)并不是直接发送它们的消息给指定的接收者(订阅者),而是将消息发布到特定的消息通道,并且不需要知道订阅者(如果有的话)的任何信息。订阅者可以订阅一个或多个感兴趣的消息通道,同时也只会收到他们感兴趣通道的信息,而不用去关心是谁发布的。这种发布者与订阅者的解耦,使其具备更强的扩展性并得到一个更加动态的网络拓扑。

    例如为了订阅通道foo和bar,客户端可以使用通道名称为参数去调用 SUBSCRIBE 命令:

    SUBSCRIBE foo bar

    其他客户端发送到消息到这些通道时,消息会由 Redis 推送到所有订阅了这些通道的客户端。

    订阅了一个或多个通道的客户端就不应该再使用命令,尽管它还能订阅其他频道或取消订阅其他通道。订阅和取消订阅的执行结果会以消息的形式返回。所以客户端能够解析这互相耦合的消息,其中第一个元素表示消息的类型。订阅了通道的客户端上允许使用的命令有 SUBSCRIBE、PSUBSCRIBE、UNSUBSCRIBE、PUNSUBSCRIBE、PING和QUIT。

    推送消息的格式

    消息是一条含有三个元素的@array-reply。第一个元素是消息的类型:

    subscribe:意味着我们已经成功订阅了第二个元素所指的通道。第三个参数表示当前已经订阅的通道总数。unsubscribe:意味着已经成功的取消了第二个元素所指的通道。第三个参数表示当前订阅的频道总数。当最后一个参数是 0 的时候,就表示不再订阅任何频道,同时客户端也可以使用Redis提供的任何命令,因为此时客户端已经退出发布/订阅状态。message:这是某一个客户端使用 PUBLISH 命令后会收到的操作结果信息。第二个元素是信息来源的频道,同时第三个参数是真实消息的内容。

    数据库与范围

    Pub/Sub 模式与 KEY 空间无关。它与任何层面无关,包括数据库数目。 在 db 10 上进行发布,db 1上的订阅者也会收到信息。 如果你需要覆盖某一些类型,把频道的前缀用一些特定的变量(test,staging,production….) 例如:

    01SUBSCRIBE first second 02*3 03$9 04subscribe 05$5 06first 07:1 08*3 09$9 10subscribe 11$6 12second 13:2

    此时,从另一个客户端上对 second 频道执行 PUBLISH 命令操作:

    1PUBLISH second Hello

    这就是前面订阅了频道的客户端收到的信息:

    1*3 2$7 3message 4$6 5second 6$5 7Hello

    现在客户端执行无参的 UNSUBSCRIBE 命令来取消自己订阅的所有频道:

    01UNSUBSCRIBE 02*3 03$11 04unsubscribe 05$6 06second 07:1 08*3 09$11 10unsubscribe 11$5 12first 13:0

    订阅的模式匹配

    Redis 的 Pub/Sub 实现支持模式匹配。客户端可以用 glob 风格的模式去接收频道名称与模式相匹配的所有频道消息。 例如:执行命令PSUBSCRIBE news.*的客户端将后收到所有发送到 news.art.figurative,news.music.jazz 等等频道的信息。所有 glob 风格的模式匹配都是有效的,同时也支持多重通配符。 执行命令PUNSUBSCRIBE news.*的客户端会取消订阅频道名称与 给定模式(news.*) 相匹配的所有频道,而其他已经订阅的频道不会爱影响。模式匹配订阅的信息格式是另一种不同的格式: 消息的类型是 pmessage:表示另一个客户端执行 PUBLISH 命令向频道发送消息,而频道符合当前客户端订阅的模式匹配。第二个元素就是匹配的模式,第三个元素就是模式匹配到的频道名称,最后一个元素就是真正的消息载体。 与系统处理 SUBSCRIBE 和 UNSUBSCRIBE, PSUBSCRIBE 和 PUNSUBSCRIBE 命令一样,发送的消息类型为 psubscribe 和 punsubscribe ,然后使用 subscribe 和 unsubscribe 一样的消息格式。

    消息同时匹配模式与订阅的频道

    一个客户端可能多次收到同一条消息,如果它订阅的多个模式匹配到了一条发布的消息,或者它订阅的模式与频道匹配到了同一条消息。例如:

    1SUBSCRIBE foo 2PSUBSCRIBE f*

    在上面的例子中,如果一条消息发送到foo频道,客户端将会收到两条消息。一个是 message类型的消息,一种是pmessage类型的消息。

    模式匹配下订阅数的意义

    在 subscribe, unsubscribe, psubscribe 和 punsubscribe 等消息类型中,最后一个参数表示仍在订阅的频道数。这个数字实际上就是客户端订阅的频道与模式的总数。 所以当客户端取消订阅所有频道和模式时,也就是这个总数值变为 0 时,客户端将会退出 Pub/Sub 模式。

    编程示例

    Pieter Noordhuis 提供了一个很好的例子,通过 EventMachine 和 Redis创建了一个多用户高性能的WEB聊天网站。

    客户端库实现提示

    由于所有的消息都会有一个订阅源。(当消息类型为 message 时,订阅源是一个频道,当消息类型为 pmessage 时,订阅源是一个模式)客户端可以利用一个HASH表将这些订阅源与回调函数绑定起来,这样当一个消息被接收后,能在 O(1) 的时间内将消息交给注册好的回调函数。

    转载自 并发编程网 - ifeve.com

    相关资源:Redis API文档
    最新回复(0)