1. 程式人生 > 資料庫 >python實現Redis訂閱釋出

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","password")
    publisher = Publisher(client)
    while True:
        publisher.publish(cctv1,input("請輸入要傳送的訊息:"))

class Channel:
    def __init__(self,name: str):
        self.name = name
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中簡單的通過字串區分頻道),但在實際中這應該是同一個物件。

結果:
在這裡插入圖片描述