了解 Redis Channel:消息传递机制、发布与订阅,以及打造简易聊天室的实战应用。

1. Redis Channel 是什么

Redis Channel 是一种消息传递机制,允许发布者向特定频道发布消息,而订阅者则通过订阅频道实时接收消息。

Redis Channel 的消息传输是通过 Redis PUB/SUB 模型实现的。发布者使用 PUBLISH 命令将消息发送到指定的频道,订阅者使用 SUBSCRIBE 命令订阅指定频道。值得注意的是,频道的主要作用是实现实时消息传递,频道信息并不存储在数据库中,而是在内存中动态生成,所以在 Redis 重启后信息将消失,如果要存储频道信息,需要引入另外的方案。

2. Redis-Cli 中演示使用

  • 订阅频道
    使用 SUBSCRIBE 命令,订阅者可以订阅感兴趣的频道,接收实时消息。例如:
    # SUBCRIBE channel1 channel2 ...
    SUBSCRIBE news
    
  • 发布消息
    通过 PUBLISH 命令,发布者可以向指定的频道发布消息。例如:
    # PUBLISH channel message
    PUBLISH news "震惊!!"
    
  • 获取所有频道
    通过 PUBSUB CHANNELS 命令,你可以获取当前被订阅的所有频道:
    PUBSUB CHANNELS
    
  • 附加
    更多的命令请参照 Redis 的 Command 文档 https://redis.io/commands/](https://redis.io/commands/

3. 利用 Channel 打造一个简易的聊天室

首先,创建一个频道用于聊天:

SUBSCRIBE chatroom1

在一个终端窗口中,使用 PUBLISH 命令发送消息:

PUBLISH chatroom1 '{"username": "u1s1", "content": "hello"}'

在另一个订阅的终端中将会接收到这个 JSON 字符串信息:

127.0.0.1:6379> SUBSCRIBE chatroom1
Reading messages... (press Ctrl-C to quit)
...
1) "message"
2) "chatroom1"
3) "{\"username\": \"y\", \"content\": \"adssd\"}"

使用 Python 来完成上面描述的需求:

import redis
import threading
import json


class ChatroomClient:
    def __init__(self, username):
        self.username = username
        self.redis_client = redis.StrictRedis(host='localhost', port=6379, db=0, password="password")
        self.channel_name = 'CHATROOM'
        self.lock = threading.Lock()

        # 启动一个子线程用于监听消息
        listen_thread = threading.Thread(target=self.listen_for_messages, daemon=True)
        listen_thread.start()

        # 等待用户输入
        self.user_publish_messages()

    def user_publish_messages(self):
        while True:
            msg = input("\n>>")
            data = {"username": self.username, "content": msg}
            self.redis_client.publish(self.channel_name, json.dumps(data, ensure_ascii=False))

    def listen_for_messages(self):
        pubsub = self.redis_client.pubsub()
        pubsub.subscribe(self.channel_name)

        while True:
            for message in pubsub.listen():
                if message["type"] == "message":
                    data = json.loads(message["data"].decode("utf8"))
                    with self.lock:
                        print(f"\n【{data['username']}】: {data['content']}")


if __name__ == "__main__":
    username = input("输入用户名: ")
    client = ChatroomClient(username)

这段代码同时实现了 “发布消息” 和 “订阅消息” 的功能:使用了一个子线程监听,当接收到消息的时候打印消息。在主线程持续等待用户输入,当用户输入后将接收到的消息以 JSON 字符串的格式发布到 Redis 中。

现在可以将上述代码复制两份,同时启动。让一个客户端的用户名为 “user1”,另一个客户端的用户名为 “user2”。在光标后发送信息。情况大致如下:
在这里插入图片描述
在图中可以看到本例在 Pycharm 中运行了 c1c2 两个客户端,在 c1 中发送了两条消息。这里需要注意,由于发送和接收信息都在一个终端中打印,所以会出现发送和接收串位的情况,无伤大雅。有需要可以自行选择别的任何方式优化。

接下来看一下 c2 的接收情况,如下图所示:
在这里插入图片描述

参考文献

Redis 指令参照 https://redis.io/commands/

  • 24
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值