首页

9.2发布消息/订阅频道

关灯 护眼    字体:

上一章 章节列表 下一章


Redis的“发布/订阅”模式是一种消息通信模式,实现了一对多的消息实时发布功能。



9.2.1 实例36:实现一对多的消息发布


实例描述

分别使用Redis的字符串和“发布/订阅”模式实现一对多的消息通信,比较这两种方式的差异。

1.使用字符串实现一对多的消息发布功能

使用字符串来实现一对多的消息发布功能,逻辑非常简单:

(1)定好一个字符串Key,例如message。

(2)发送端使用字符串的set操作把新信息设置到这个Key中。

(3)多个接收端不停获取 message 的值。如果发现值变化了,则认为来了新的消息,接收并保存。

使用字符串实现一对多的消息发布功能,代码分为发送端和接收端。

(1)发送端代码:

代码9-8 使用字符串实现一对多的消息发布(发送端代码)

其中,主要代码说明如下。

● 第8行代码:使用一个无限循环来实现持续发布消息。

● 第9行代码:让用户在命令行输入需要发布的信息。

● 第10行代码:记录当前的时间,时间格式为“2018-08-19 11:29:12”。

● 第11行代码:把信息和时间组装为一个字典。

● 第12行代码:以JSON格式把信息设置到Redis的message字符串中。

(2)接收端的代码如下:

代码9-9 使用字符串实现一对多的消息发布(接收端代码)



其中,主要代码说明如下。

● 第7行代码:初始化时间记录变量。

● 第8行代码:使用一个无限循环来持续接收数据。

● 第9行代码:读取Redis中名字为message的字符串。

● 第10~12行代码:message这个Key可能不存在,此时返回None。遇到这种情况就等待1秒以后跳过本次循环。

● 第 13~15行代码:使用json模块解析JSON字符串,以获取信息和发送时间。

● 第16~19行代码:如果信息的发送时间与上一条信息的发送时间一样,则说明是同一条信息,不需要打印出来。

● 第21行代码:更新时间记录变量。

发送端的运行效果如图9-10所示。

图9-10 发送端运行效果

接收端的运行效果如图9-11所示。

图9-11 接收端运行效果

2.使用字符串的弊端

使用字符串进行消息的发布,虽然说代码简单易懂,但它也存在诸多问题。举例如下:

● 接收端不知道发送端什么时候发布消息,因此必须持续不断检查Redis,浪费系统资源。

● 由于轮询查询,所以消息有延迟。

● 如果发送端在1秒内连续更新10条,则后一条会覆盖前一条,而接收端每1秒才获取一次数据,必然导致最多漏掉9条数据。要减少遗漏数量就需要增加轮询频率,进一步增大系统开销。

3.使用Redis的“发布/订阅”模式实现消息通信

“发布/订阅”模式是 Redis 自带的一对多消息通信模式。使用“发布/订阅”模式不仅可以解决字符串通信遇到的各种问题,而且代码更简洁。

(1)发送端代码如下。

代码9-10 使用“发布/订阅”模式实现一对多消息通信(发送端代码)

其中,主要代码说明如下。

● 第8行代码:进入无限循环,不停发布信息。

● 第9行代码:获取用户在命令行输入的内容。

● 第10行代码:获取当前的时间,并转化为“2018-08-19 13:23:00”这种格式。

● 第11行代码:把信息和当前时间组装为一个字典。

● 第12行代码:把信息以JSON字符串的形式发布到名为pubinfo的频道中。

(2)接收端代码如下。

代码9-11 使用“发布/订阅”模式实现一对多消息通信(接收端代码)

其中,主要代码说明如下。

● 第5行代码:生成一个发布/订阅对象,并忽略订阅成功的消息。

● 第6行代码:订阅名为pubinfo的频道。

● 第7~9行代码:从频道中获取信息并打印。



9.2.2 实例37:在Python中发布消息/订阅频道


实例描述

在Python中操作Redis,使用“发布/订阅”模式实现以下功能:

(1)向一个频道中发布消息。

(2)订阅多个频道。

“发布/订阅”模式在Redis中只有6个命令,对应到Python中有6个方法。

1.发布消息

在Python中向一个频道发送消息,代码和向Redis字符串设置值一样简单,差别只是使用的方法名为“publish”,格式如下:

client.publish(’频道名’, ’消息’)

例如代码9-12。

代码9-12 使用Python向一个频道发布消息

2.订阅频道

订阅频道涉及的步骤稍微多一些。首先需要生成一个“发布/订阅”对象,然后使用这个对象来订阅频道。订阅频道以后,循环从频道里面获取数据。

(1)一个订阅实例只订阅一个频道。

格式为:

代码9-13 使用Python订阅频道

第3行的instener.listen()是一个阻塞式的方法。程序运行到这里,如果频道里面没有数据,则程序就会“卡住”,直到频道里面有了新的信息,才会继续运行后面的代码。

第3行的for循环获得的message是一个字典,它的内容有两种
m.qiduwx.com提示您,本章没有阅读完,点击下一页进入下一页阅读!

上一章 章节列表 下一章