Redis(1.6)Redis发布订阅
【0】发布订阅架构图

客户端订阅某个频道,让后有人在频道上发布信息,频道就分发给所有的客户端。
举个例子:就和微信公众号一样,文章作者者把文章发到微信公众号上,微信公众号平台把文章推送到所有的订阅用户上。
应用场景:
(1)在博客网站中,有100个粉丝订阅了你,当你发布新文章时,就可以推送消息给他们。
(2)微信公众号模式
(3)类似于开发设计模式中的 观察者模式
【1】命令
【1.1】订阅频道
subscribe channel1 channel2..... 订阅一个或多个指定的频道 subscribe cctv1 cctv2
psubscribe pattern1 parttern2.... 订阅一个或多个符合特定模式的频道 psubscribe cctv*
【1.2】发布频道信息
publish channel1 message1 将 message1 发送到指定的 channel1 频道 publish cctv1 hello
publish numsub channel:channel1 查看 channel1频道中有多少订阅
【1.3】退订频道
unsubscribe channel1 channel2..... 退订一个或多个指定的频道 subscribe cctv1 cctv2
punsubscribe pattern1 pattern2..... 退订一个或多个特定模式的频道 publish cctv*
【2】实操演示
【2.1】订阅频道 subscribe channel1

【2.2】发布频道信息 publish channel messages1
如果当前频道没有任何订阅者,下图中第2行会显示0,否则有n个订阅者这里就会显示n。

【2.3】查看消息
客户端1:发布消息

客户端2:接受消息

【2.4】特定模式的订阅与消息查收
命令操作顺序
(1)psubscribe cctv*(session1)
(2)publish cctv1 'hello,cctv1'(session2)
(3)publish cctv2 'hello,cctv2'(session2)
且,其接受消息的 message 字段显示成了 pmessage
session1

session2

【3】基本运作原理
每个Redis 服务器进程都维持着一个表示服务器状态的 redis.h/redisServer结构, 结构的pubsub_channels 属性是一个字典, 这个字典就用于保存订阅频道的信息:
struct redisServer {
// ...
dict *pubsub_channels;
// ...
};
其中,字典的键为正在被订阅的频道, 而字典的值则是一个链表, 链表中保存了所有订阅这个频道的客户端。
比如说,在下图展示的这个pubsub_channels示例中,client1 、 client2 和 client3 就订阅了 channel1 , 而client3也同时订阅了channel2。
当客户端调用SUBSCRIBE命令时, 程序就将客户端和要订阅的频道在pubsub_channels字典中关联起来。

SUBSCRIBE 命令的行为可以用伪代码表示如下:

def SUBSCRIBE(client, channels):
// 遍历所有输入频道
for channel in channels:
// 将客户端添加到链表的末尾
redisServer.pubsub_channels[channel].append(client)

通过pubsub_channels字典, 程序只要检查某个频道是否为字典的键, 就可以知道该频道是否正在被客户端订阅; 只要取出某个键的值, 就可以得到所有订阅该频道的客户端的信息。
了解了pubsub_channels字典的结构之后, 解释PUBLISH命令的实现就非常简单了: 当调用PUBLISH channel message命令, 程序首先根据channel定位到字典的键, 然后将信息发送给字典值链表中的所有客户端。
订阅模式
redis的发布订阅不仅仅提供简单的订阅频道,还提供模式匹配订阅。模式订阅使用命令PSUBSCRIBE实现。
redisServer.pubsub_patterns属性是一个链表,链表中保存着所有和模式相关的信息:
struct redisServer {
// ...
list *pubsub_patterns;
// ...
};
链表中的每个节点都包含一个redis.h/pubsubPattern结构:
typedef struct pubsubPattern {
redisClient *client;
robj *pattern;
} pubsubPattern;
client 属性保存着订阅模式的客户端,而 pattern 属性则保存着被订阅的模式。
每当调用 PSUBSCRIBE命令订阅一个模式时, 程序就创建一个包含客户端信息和被订阅模式的pubsubPattern结构, 并将该结构添加到redisServer.pubsub_patterns链表中。
作为例子,下图展示了一个包含两个模式的 pubsub_patterns 链表, 其中 client123 和 client256 都正在订阅 tweet.shop.* 模式:

通过遍历整个pubsub_patterns链表,程序可以检查所有正在被订阅的模式,以及订阅这些模式的客户端。
当执行PUBLISH进行命令向channel命令发送消息时,PUBLISH除了将message 发送到所有订阅channel的客户端之外, 它还会将channel和pubsub_patterns中的模式进行对比,。
如果channel和某个模式匹配的话, 那么也将message 发送到订阅那个模式的客户端,例如一个客户端订阅了aa.bb.*频道,那么他会收到来自所有aa.bb开头的所有频道消息。
参考:https://www.cnblogs.com/wdliu/p/9360286.html
Redis(1.6)Redis发布订阅的更多相关文章
- 第三百零一节,python操作redis缓存-管道、发布订阅
python操作redis缓存-管道.发布订阅 一.管道 redis-py默认在执行每次请求都会创建(连接池申请连接)和断开(归还连接池)一次连接操作,如果想要在一次请求中指定多个命令,则可以使用pi ...
- Redis学习笔记8--Redis发布/订阅
发布订阅(pub/sub)是一种消息通信模式,主要的目的是解耦消息发布者和消息订阅者之间的耦合,这点和设计模式中的观察者模式比较相似.pub /sub不仅仅解决发布者和订阅者直接代码级别耦合也解决两者 ...
- Spring Boot使用Redis进行消息的发布订阅
今天来学习如何利用Spring Data对Redis的支持来实现消息的发布订阅机制.发布订阅是一种典型的异步通信模型,可以让消息的发布者和订阅者充分解耦.在我们的例子中,我们将使用StringRedi ...
- Redis基础知识 之——发布/订阅
一.说明: 订阅,取消订阅和发布实现了发布/订阅消息范式(引自wikipedia),发送者(发布者)不是计划发送消息给特定的接收者(订阅者).而是发布的消息分到不同的频道,不需要知道什么样的订阅者订阅 ...
- Spring Data Redis实现消息队列——发布/订阅模式
一般来说,消息队列有两种场景,一种是发布者订阅者模式,一种是生产者消费者模式.利用redis这两种场景的消息队列都能够实现. 定义:生产者消费者模式:生产者生产消息放到队列里,多个消费者同时监听队列, ...
- redis实现消息队列&发布/订阅模式使用
在项目中用到了redis作为缓存,再学习了ActiveMq之后想着用redis实现简单的消息队列,下面做记录. Redis的列表类型键可以用来实现队列,并且支持阻塞式读取,可以很容易的实现一个高性 ...
- Redis(二)-- 发布订阅、事务、安全、持久化
一.Redis发布订阅 Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息. 打开两个窗口:session1 和 session2 在sess ...
- Redis实现消息的发布/订阅
利用spring-boot结合redis进行消息的发布与订阅: 发布: class Publish { private static String topicName = “Topic:chat”; ...
- redis之mq实现发布订阅模式
示例代码-github 概述 Redis不仅可作为缓存服务器,还可用作消息队列,本示例演示如何使用redis实现发布/订阅消息队列. 在Redis中,发布者没有将消息发送给特定订阅者的程序.相反,发布 ...
- PHP使用Redis的Pub/Sub(发布订阅)命令
1.概念 名称 含义 channel 频道:生产者和消费者直接操作的对象 publish 生产者:向channel发送消息 subscribe 消费者:订阅一个或多个channel psubscrib ...
随机推荐
- JS核心知识点:DOM\BOM\EVENT
1.DOM(Document Object Model) :文档对象模型2. DOM节点:页面中最基本的组成部分 3. childNodes:获取某个节点下所有的子节点 在标准及ie9以上 : 会获取 ...
- 牛券Cow Coupons
USACO12FEB 久违的奶牛题. 题意: FJ准备买一些新奶牛,市场上有 $ N $ 头奶牛 $ (1 \leq N \leq 50000) $ ,第i头奶牛价格为 $ P_i (1 \leq P ...
- leetcode题目234.回文链表(快慢指针+辅助空间-简单)
题目描述: 请判断一个链表是否为回文链表. 示例 1: 输入: 1->2 输出: false 示例 2: 输入: 1->2->2->1 输出: true 进阶: 你能否用 O( ...
- Netfilter 之 连接跟踪初始化
基础参数初始化 nf_conntrack_init_start函数完成连接跟踪基础参数的初始化,包括了hash,slab,扩展项,GC任务等: int nf_conntrack_init_start( ...
- curl_setopt(ch, option, value)函数上传文件
bool curl_setopt ( resource $ch , int $option , mixed $value ) 为给定的cURL会话句柄设置一个选项 详细介绍请到:http://www. ...
- Python可变参数函数用法详解
来自:http://c.biancheng.net/view/2257.html 很多编程语言都允许定义个数可变的参数,这样可以在调用函数时传入任意多个参数.Python 当然也不例外,Python ...
- Makefile.am和makefile.in生成Makefile
Makefile.am和makefile.in生成Makefile 很多时候,我们在网上下载的linux开源软件都会遇到一个问题,就是源码里面没有直接的makefile,但是它有Makefile.am ...
- xpath定位元素
@ 表示包含的属性,如@id表示包含id属性的标签[] 表示索引.. 表示父节点 --------------------------------------------------- //* #定位 ...
- JavaScript抽象语法树英文对照
type:"Program" //顶级对象类型 type:"Identifier" // 标识符 type:"FuncationDeclaration ...
- git配置过程中fatal:拒绝合并无关的历史
首先将远程仓库和本地仓库关联起来: git branch --set-upstream-to=origin/master master 然后使用git pull整合远程仓库和本地仓库, git pul ...