20 发布订阅 相关操作

Posted 蓝风9

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了20 发布订阅 相关操作相关的知识,希望对你有一定的参考价值。

前言

相关介绍主要围绕着 redis 里面的发布订阅相关特性 

如下常用的命令来自于我们常见的教程 : Redis 发布订阅 | 菜鸟教程 

本文的相关代码 拷贝自 redis-6.2.0  

代码来自于 https://redis.io/  

redis 发布订阅机制

订阅 redis-cli 这边订阅了给定的 channel 或者 channelList 或者 channelPattern 或者 channelPatternList, 然后订阅的客户端 阻塞于此, 等待 redis-server 发送消息给客户端 

服务器这边 接收到客户端订阅了 channel 或者 channelList 或者 channelPattern 或者 channelPatternList, 注册到注册列表里面 

当其他 redis-cli 向这个 channel 发布了一个消息, 服务器接收到了这个 publish 请求之后, 查询注册的 [channel -> clients], [channelPattern -> clients], 查询需要推送消息的 客户端, 依次给客户端推送消息 

我们这里主要是调试一下 订阅 发布 的这一整个流程, 从 redis-cli, redis-server 的角度来剖析一下 

1. redis-cliA 订阅 channel 

2. redis-server 对于 redis-cliA 订阅 channel 的处理 

3. redis-cliB 发布消息到 channel 

4. redis-server 对于 redis-cliB 发布消息的处理 

5. redis-cliA 接收到 redis-server 这边推送到消息的处理 

1. redis-cliA 订阅 channel 

redis-cli 这边发送了 "subscribe ch" 命令, 发送了命令之后, 客户端这边的处理是 输出 "Reading messages... (press Ctrl-C to quit)" 

然后之后就是 循环读取服务端发送过来的数据, 输出到 redis-cli 中 

2. redis-server 对于 redis-cliA 订阅 channel 的处理 

给定的客户端 订阅 给定的 channel 

将 channel -> client 注册到 serrver.pubsub_channels[channel -> [client1, client2, ...] ] 里面, 注册 [channel -> null] 到 client.pubsub_channels 

然后返回 subscribe 的响应给客户端, 相应的数据为 [subscribe, channel, 客户端订阅的渠道数量] 

相应的 redis-cli 这边一直在阻塞读取 redis-server 的响应, 读取出来之后, 输出如下, 表示 subscribe 命令, 订阅的是 ch 这个channel, client 总共订阅了 1 个 channel 

1) "subscribe"
2) "ch"
3) (integer) 1

3. redis-cliB 发布消息到 channel 

这个就是一个 普通的 发送命令给 redis-server, 然后读取 redis-server 的回复 

发送 "publish ch xx" 给 redis-server 

4. redis-server 对于 redis-cliB 发布消息的处理 

可以看到 publish 这边有两部分的处理, 一部分是遍历 pubsub_channels[对应于 subscribe], 一部分是遍历 pubsub_patterns[对应于 psubscribe] 

首先是遍历这部分精确匹配的 channel, 找到注册的 clients, 循环发送消息 

然后遍历这部分根据 pattern匹配的 channel, 找到注册的 clients, 循环发送消息 

最终返回 n个客户端接受到的消息的数量(逻辑上可能存在重复发送给某一个客户端) 

如果是 精确匹配的channel, 返回给客户端的是 ["message", channel, message], 如果是 pattern匹配, 返回给客户端的是 ["pmessage", pattern, channel, message]

5. redis-cliA 接收到 redis-server 这边推送到消息的处理 

依旧是阻塞读取 服务端返回的数据, 然后输出数据 

精确匹配时 redis-server 返回给客户端的数据, redis-cli 输出如下 

1) "message"
2) "ch"
3) "abc"

pattern匹配时 redis-server 返回给客户端的数据, redis-cli 输出如下 

1) "pmessage"
2) "c*"
3) "ch"
4) "abc"

关于 psubscribe 

给定的客户端 订阅 给定的 channelPattern 

将 channelPattern -> client 注册到 serrver.pubsub_patterns[channelPattern -> [client1, client2, ...] ] 里面, 注册 [channelPattern -> null] 到 client.pubsub_patterns 

然后返回 psubscribe 的响应给客户端, 相应的数据为 [psubscribe, channelPattern, 客户端订阅的渠道数量] 

关于 unsubscribe 

给定的客户端 移除注册 给定的 channel 

将 channel -> client 移除注册的 serrver.pubsub_channels[channel -> [client1, client2, ...] ] 里面, 移除注册的 [channel -> null] 到 client.pubsub_channels 

然后返回 unsubscribe 的响应给客户端, 相应的数据为 [unsubscribe, channel, 客户端订阅的渠道数量] 

关于 punsubscribe 

给定的客户端 移除注册 给定的 channelPattern 

将 channelPattern -> client 移除注册的 serrver.pubsub_patterns[channelPattern -> [client1, client2, ...] ] 里面, 移除注册的 [channelPattern -> null] 到 client.pubsub_patterns 

然后返回 punsubscribe 的响应给客户端, 相应的数据为 [punsubscribe, channelPattern, 客户端订阅的渠道数量] 

完 

以上是关于20 发布订阅 相关操作的主要内容,如果未能解决你的问题,请参考以下文章

与订阅返回相关的 lint 错误,其中包含多个操作

大数据之Redis:Redis的发布和订阅

取消订阅 Rxjs finalize 操作符

Web 开发人员需要订阅哪些重要的订阅源?

贝宝订阅下一个付款日期

将 Stripe 结帐会话与订阅 webhook 关联