python实现Redis订阅发布

Redis 发布订阅

Redis 发布订阅可以用在像消息通知,群聊,定向推送,参数刷新加载等业务场景

发布订阅模型有三个角色:

  1. 发布者(Publisher)
  2. 订阅者(Subscriber)
  3. 频道(channel)

每个订阅者可以订阅多个频道,发布者可以在某个频道里发布消息,订阅者会接受到自己订阅频道里发布的消息。

1.相关命令 (参考)

publish channel message         发布消息
subscribe [channel]             订阅频道
unsubscribe [channel]           取消订阅
psubscribe [pattern...]         订阅指定模式的频道
punsubscribe [pattern...]       退订指定模式的频道
pubsub channels                 列出至少有一个订阅者的频道
pubsub numsub [channel...]      列表给定频道的订阅者数量
pubsub numpat                   列表被订阅模式的数量 

在终端使用示例

# 在 终端1 订阅cctv1
127.0.0.1:8100> subscribe cctv1
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "cctv1"
3) (integer) 1
# 在 终端2 向cctv1 发布消息
127.0.0.1:8100> publish cctv1 "this is cctv1"
(integer) 1
# 终端1 接受到终端2发的消息
127.0.0.1:8100> subscribe cctv1
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "cctv1"
3) (integer) 1
1) "message"
2) "cctv1"
3) "this is cctv1"

2. python 实现

订阅者类,只写了订阅功能,退订原理是一样的,偷了懒,把订阅频道和接收消息写到了一个方法里面,如果严格按面向对象的思想应该分开。

from PublishAndSubscribe.Channel import Channel
from PublishAndSubscribe.RedisTool import RedisTool


class Subscriber:
    def __init__(self, conn):
        self._conn = conn

    def subscribe(self, channel: Channel):
        # 获取发布/订阅对象
        pub = self._conn.pubsub()
        # 选择要订阅的频道
        pub.subscribe(channel.name)
        while True:
            # 接收消息
            msg = pub.parse_response()
            print(msg)


if __name__ == '__main__':
    client = RedisTool.redis_connection("0.0.0.0", 8100, "password")
    cctv1 = Channel("CCTV1")
    Subscriber(client).subscribe(cctv1)

发布者类

from PublishAndSubscribe.Channel import Channel
from PublishAndSubscribe.RedisTool import RedisTool


class Publisher:
    def __init__(self, conn):
        self._conn = conn

    def publish(self, channel: Channel, mess: str):
        # 向特定频道发布消息
        self._conn.publish(channel.name, mess)


if __name__ == '__main__':
    cctv1 = Channel("CCTV1")
    client = RedisTool.redis_connection("0.0.0.0", 8100, "password")
    publisher = Publisher(client)
    while True:
        publisher.publish(cctv1, input("请输入要发送的消息:"))

频道类,Redis中频道的概念只是一个字符串

class Channel:
    def __init__(self, name: str):
        self.name = name

一个工具类,用来连接redis

import redis


class RedisTool:
    @staticmethod
    def redis_connection(address: str, port: int, password: str):
        """
        用来连接Redis
        Args:
            address: Redis 服务端IP地址
            port: [int] Redis 服务端口
            password: Redis client 登录凭证
        Return:
            type[Redis]: 返回一个redis对象
        """
        return redis.StrictRedis(address, port, password=password)
  • 为了简便在订阅者和发布者两处都实例化了一个“CCTV1”的频道,虽然用起来不会有什么问题(Redis中简单的通过字符串区分频道),但在实际中这应该是同一个对象。

结果:
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Junebao

如果你碰巧财力雄厚的话...

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值