一、概述
1、redis通过publish、subscribe等命令实现了订阅与发布模式。
2、这个功能提供两种信息机制,分别是订阅/发布到频道和订阅/发布到模式。

二、频道的订阅与信息发送
1、redis的subscribe命令可以让客户端订阅任意数量的频道,每当有新信息发送到被订阅的频道时,信息就会被发送给所有订阅指定频道的客户端。
2、作为例子,下图展示了频道channel1,以及订阅这个频道的三个客户端------client2、client5和client1之间的关系:

3、当有新消息通过publish命令发送给频道channel1时,这个消息就会被发送给订阅它的三个客户端:

4、每个redis服务器进程都维持着一个表示服务器状态的redis.h/redisServer结构,结构的pubsub_channels属性是一个字典,这个字典就用于保存订阅频道的信息;
5、其中,字典的键为正在被订阅的频道,而字典的值则是一个链表,链表中保存了所有订阅这个频道的客户端

6、比如说,在下图展示的这个pubsub_channels示例中,client2、client5和client1就订阅了channel1,而其他频道也分别被别的客户端所订阅:

7、当客户端调用subscribe命令时,程序就将客户端和要订阅的频道在pubsub_channels字典中关联起来;
8、举个例子,如果客户端client10086执行命令subscribe channel1 channel2 channel3,那么前面只是的pubsub_channels将变成下面这个样子

8、通过pubsub_channels字典,程序只要检查某个频道是否为字典的键,就可以知道该频道是否正在被客户端订阅;只要去除某个键的值,就可以得到所有订阅该频道的客户端的信息。

9、了解了pubsub_channels字典的结构之后,解释publish命令的实现就非常简单了:当调用publish channel message命令,程序首先根据channel定位到字典的键,然后将信息发送给字典值链表中的所有客户端。

10、使用unsubscribe命令可以推定指定的频道,这个命令执行的是订阅的反操作:他从pubsub_channels字典的给定频道(键)中,删除关于当前客户端的信息,这样被退订频道的信息就不会再发送给这个客户端。

三、模式的订阅与信息发送
(一)订阅模式
1、当使用publish命令发送信息到某个频道时,不仅所有订阅该频道的客户端会受到信息,如果有某个/某些模式和这个频道匹配的话,那么所有订阅这个/这些频道的客户端也同样会收到信息。

2、下图展示了一个带有频道和模式的例子,其中tweet.shop.*模式匹配了tweet.shop.kindle频道和tweet.shop.ipad频道,并且有不同的客户端分别订阅他们三个:

3、当有信息发送到tweet.shop.kindle频道时,信息除了发送给clientX和clientY之外,还会发送给订阅tweet.shop.*模式的client123和client256

4、redisServer.pubsub_patterns属性是一个链表,链表中保存着所有和模式相关的信息:
  struct redisServer{
    //...
    list *pubsub_patterns;
    //...
  }
链表中的每个节点都包含一个reids.h/pubsubPattern结构:
  typedef struct pubsubPattern{
    redisClient *client;//哪一个客户端
    robj *pattern;//订阅的那个模式
  }pubsubPattern;

client属性保存着订阅模式的客户端,而pattern属性则保存着被订阅的模式。
每当调用PSUBSCRIBE命令订阅一个模式时,程序就创建一个包含客户端信息和被订阅模式的pubsubPattern结构,并将该结构添加到redisServer.pubsub_patterns链表中。

下图展示了一个包含两个模式的pubsub_patterns链表,其中client123和client256都正在订阅tweet.shop.*模式:

如果这时客户端client10086执行PSUBSCRIBE broadcast.list.*,那么pubsub_patterns链表将被更新成这样:

(二)发送信息到模式
PUBLISH除了将message发送到所有订阅channel的客户端之外,它还会降channel和pubsub_patterns中的模式进行对比,如果channel和某个模式匹配的话,那么也将message发送到订阅那个模式的客户端。

举个例子,如果redis服务器的pubsub_patterns状态如下:

那么当某个客户端发送信息"Amazon Kindle,$69."到tweet.shop.kindle频道时,除了所有订阅了tweet.shop.kindle频道的客户端会受到信息之外,客户端client123和client256页同样会收到信息,因为这两个客户端订阅的tweet.shop.*模式和tweet.shop.kindle频道匹配。

(三)退订模式
使用PUNSUBSCRIBE命令可以退订指定的模式,这个命令执行的是订阅模式的反操作:程序会删除redisServer.pubsub_patterns链表中,所有和被退订模式相关联的pubsubPattern结构,这样客户端就不会再收到和模式相匹配的频道发来的信息。

四、redis订阅与发布系统的基本命令

  • 命令名称:subscribe
  • 语法:subscribe channel [channel ...]
  • 功能:
    • 订阅给定的一个或多个频道的信息。
  • 返回值:
    • 接收到的信息。
  • 命令名称:psubscribe
  • 语法:psubscribe pattern [pattern ...]
  • 功能:
    • 订阅一个或多个符合给定模式的频道。
    • 每个模式以*作为匹配符,比如it*匹配所有以it开头的频道(it.news、it.blog、it.tweets等)
  • 返回值:
    • 接收到的信息。
  • 命令名称:publish
  • 语法:publish channel message
  • 功能:1)将信息message发送到指定的频道channel
  • 返回值:1)接收到信息message的订阅者数量。
  • 命令名称:unsubscribe
  • 语法:unsubscribe [channel[channel...]]
  • 功能:
    • 指示客户端退订所有给定频道。
    • 如果没有频道被指定,也即是,一个无参数的unsubscribe调用被执行,那么客户端使用subscribe命令订阅的所有频道都会被退订。在这种情况下,命令会返回一个信息,告知客户端所有被退订的频道。
  • 返回值:
    • 退订结果。
  • 命令名称:punsubscribe
  • 语法:punsubscribe [channel[channel...]]
  • 功能:
    • 指示客户端退订所有给定模式。
    • 如果没有模式被指定,也即是,一个无参数的punsubscribe调用被执行,那么客户端使用subscribe命令订阅的所有模式都会被退订。在这种情况下,命令会返回一个信息,告知客户端所有被退订的模式。
  • 返回值:
    • 退订结果。
  • 命令名称:pubsub
  • 语法:pubsub <subcommand> [argument [argument...]]
  • 功能:
    • pubsub是一个查看订阅与发布系统装填的内省命令,它由数个不同格式的子命令组成。
  • 子命令:
    • pubsub channels [pattern]

      • 列出当前的活跃频道。
      • 活跃频道指的是那些至少有一个订阅者的频道,订阅模式的客户端不计算在内。
      • 如果不给出pattern参数,那么列出订阅与发布系统中的所有活跃频道。
      • 如果给出pattern参数,那么只列出和给定模式pattern相匹配的那些活跃频道。
    • pubsub numsub [channel-1 ... channel-N]
      • 返回给定频道的订阅者数量,订阅模式的客户端不计算在内。
    • pubsub numpat
      • 返回订阅模式的数量。
      • 注意:这个命令返回的不是订阅模式的客户端的数量,而是客户端订阅的所有模式的数量总和。

redis订阅与发布系统的更多相关文章

  1. Redis订阅和发布模式和Redis事务

    -------------------Redis订阅和发布模式------------------- 1.概念     Redis 发布订阅(pub/sub)是一种消息通信模式:     发送者(pu ...

  2. Redis订阅与发布

    发布与订阅模型在许多编程语言中都有实现,也就是我们经常说的设计模式中的一种--观察者模式.在一些应用场合,例如发送方并不是以固定频率发送消息,如果接收方频繁去咨询发送方,这种操作无疑是很麻烦并且不友好 ...

  3. redis 订阅与发布

    PUBLISH,SUBSCRIBE,等命令实现订阅与发布 订阅/发布到频道 订阅/发布到模式   频道的订阅与信息发送   订阅subscribe,可以让客户端订阅任意数量的频道, 每当有新信息发送到 ...

  4. redis订阅与发布(把redis作为消息中间件)

    订阅频道127.0.0.1:6379> subscribe chat1Reading messages... (press Ctrl-C to quit)1) "subscribe&q ...

  5. websocket+nodejs+redis实现消息订阅和发布系统

    其实我很懒,不想打字,代码已上传到码云,请点此处. 有疑问请一下扫描二维码,加我微信:

  6. PHP swoole实现redis订阅和发布

    前戏:实现用户下单,服务器通知后台接收订单...类似美团外卖 1.首先要实现一个订阅程序 $result = $client->connect('127.0.0.1', 6379, functi ...

  7. 上下文管理、线程池、redis订阅和发布

    一:上下文管理: 对于一些对象在使用之后,需要关闭操作的.比如说:socket.mysql数据库连接.文件句柄等. 都可以用上下文来管理. 语法结构: Typical usage: @contextm ...

  8. Redis 订阅发布 - Jedis实现

    Redis 订阅发布 - Jedis实现 我想到使用Redis的订阅发布模式是用来解决推送问题的-. 对于概念性的叙述,多多少少还是要提一下的: ​ 什么是Redis发布订阅?Redis发布订阅是一种 ...

  9. Redis的消息发布和订阅

    Redis的消息发布和订阅 Author:SimpleWu GitHub-redis 什么是消息发布和订阅? Redis 发布订阅(pub/sub)是一种进程间的消息通信模式: 发送者(pub)发送消 ...

随机推荐

  1. 前端微信小程序电影类仿淘票票微信小程序

    需求描述及交互分析设计思路和相关知识点电影界面顶部页签切换效果设计正在热映界面布局设计即将上映界面布局设计电影详情页设计我的界面列表导航设计登录设计 相关知识点(1)swiper滑块视图容器组件,可以 ...

  2. Web前端鼠标悬停实现显示与隐藏效果

    css定义,偏移量,相对定位,绝对定位 显示与隐藏 二维码相对于微信图标定位 鼠标悬停微信图标上显示 鼠标离开微信图标时隐藏 什么是定位,就是定义网页标签在运行时显示的位置 css提供Position ...

  3. allure-pytest 测试报告分享给大家

    allure-pytest生成测试报告,经过实践得出如下经验,参考了很多大神的博客一并附上 1.安装allure-pytest pip install allure-pytest 2.执行命令生成js ...

  4. Pyton项目打包成exe文件

    Python项目打包成exe文件 1 系统环境 windows版本: Win7 64位 python环境:Anaconda python版本:3.6 64位 pyinstaller版本:3.5 1 安 ...

  5. Eclipse R语言开发环境搭建 StatET插件

    StatET 官网 http://www.walware.de/goto/statet Installation 点击菜单栏 help --> Install New Software 配置R语 ...

  6. OpenFOAM——高空腔内的湍流自然对流

    本算例来自<ANSYS Fluid Dynamics Verification Manual>中的VMFL052: Turbulent Natural Convection Inside ...

  7. java.lang.NumberFormatException: Infinite or NaN原因之浮点类型除数为0结果探究

    背景 在对Double类型的数据进行计算操作,将结果转化为BigDecimal时抛出了下面的异常,进行了Debug才发现了问题原因,同时也暴露出了自己在一些基础知识上还有些欠缺. Exception ...

  8. python unittest套件加载用例时,出现No tests were found,Empty test suite

    错误信息: 之前运行好好的脚本,突然报No tests were found,Empty test suite,详情错误信息如下所示: Launching pytest with arguments ...

  9. spring boot后端使用fastjson,错误代码415, 500

    $.post({ url: "/register", dataType: "json", contentType: "application/json ...

  10. TCP Keepalive笔记

    TCP是无感知的虚拟连接,中间断开两端不会立刻得到通知.一般在使用长连接的环境下,需要心跳保活机制可以勉强感知其存活.业务层面有心跳机制,TCP协议也提供了心跳保活机制. 长连接的环境下,人们一般使用 ...