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 发布订阅 相关操作的主要内容,如果未能解决你的问题,请参考以下文章