实时聊天消息应用程序的普及率呈指数级增长。WhatsApp、Facebook、Telegram、Slack、Discord 等移动应用程序已成为我们生活的一部分。用户沉迷于这些实时聊天移动应用程序对话,因为它们带来了个人化的触感并提供了实时互动。
越来越多的社交媒体应用程序将社交元素引入其中,以实现协作、消息传递、社交互动和评论等活动。此类活动需要实时功能才能自动向用户展示更新的信息。越来越多的开发人员正在利用 Redis 的强大功能,因为它速度极快,并且支持各种丰富的数据结构,例如列表、集合、排序集、哈希等。Redis 同时附带 Pub/Sub 消息功能,使开发人员能够通过生成多个服务器实例来扩展后端。
在本教程中,我们将了解如何构建一个使用 Flask、Socket.IO 和 Redis Cloud 在 Amazon Web Services 上运行的实时聊天应用程序。此示例使用发布/订阅功能结合 WebSockets 来实现客户端和服务器之间的消息通信。
按照本教程 注册免费的 Redis Cloud 帐户。如果您已有现有帐户,则只需要您的登录凭据来访问您的订阅。
在创建新订阅时选择 AWS 作为云供应商。在创建新数据库时,请确保设置自己的密码。在数据库创建过程结束时,您将获得 Redis Cloud 数据库端点和端口。保存这些信息,您以后会需要它们。
您无需创建 AWS 帐户即可设置 Redis 数据库。AWS 上的 Redis Cloud 是一款完全托管的数据库即服务,数千个客户信赖它提供高性能、无限可扩展性、真正的高可用性和一流的支持。
git clone https://github.com/redis-developer/basic-redis-chat-app-demo-python
cd client
yarn install
yarn start
You can now view client in the browser.
Local: https://localhost:3000
On Your Network: https://192.168.1.9:3000
cd ..
pip3 install -r requirements.txt
python3 -m venv venv/
source venv/bin/activate
python3 app.py
* Restarting with stat
* Debugger is active!
* Debugger PIN: 220-696-610
(8122) wsgi starting up on https://127.0.0.1:5000
聊天应用程序服务器作为基本的 REST API 工作,其中涉及在聊天室中维护会话和处理用户状态(除了 WebSocket/实时部分)。服务器启动时,会发生初始化步骤。首先,建立新的 Redis 连接并检查是否需要加载演示数据。
为简单起见,检查具有 total_users 值的键:如果它不存在,我们用初始数据填充 Redis 数据库。EXISTS total_users(检查键是否存在)演示数据初始化分为多个步骤。
我们创建一个新的用户 ID:INCR total_users。然后我们通过用户名设置用户 ID 查找键:例如
SET username:nick user:1
最后,其余数据将写入哈希集
HSET user:1 username "nick" password "bcrypt_hashed_password".
此外,每个用户都将添加到默认的“General”房间。为了处理每个用户的房间,我们有一个集合,其中包含房间 ID。以下是如何添加房间的示例命令
SADD user:1:rooms "0"
首先,创建私人房间:如果需要建立私人房间,则为每个用户生成一个房间 ID:room:1:2,其中数字对应于用户 ID(按升序排列)。
例如,在 2 个用户之间创建私人房间
SADD user:1:rooms 1:2 and SADD user:2:rooms 1:2
然后,我们通过写入排序集,为每个对话添加消息到此房间
ZADD room:1:2 1615480369 "{'from': 1, 'date': 1615480369, 'message': 'Hello', 'roomId': '1:2'}"
我们使用字符串化的 JSON 来保留消息结构并简化此演示应用程序的实现细节。您可以选择使用哈希或 JSON
消息将添加到“General”房间的排序集中,该房间的 ID 为:room:0
初始化后,将创建一个发布/订阅订阅:SUBSCRIBE MESSAGES。同时,每个服务器实例都会在该频道上的消息上运行一个监听器,以接收实时更新。
同样,为简单起见,每条消息都将序列化为 JSON,然后以与 WebSocket 消息相同的方式进行解析和处理。
发布/订阅允许连接在不同平台上编写的多个服务器,而无需考虑每个服务器的实现细节。
建立 WebSocket 连接后,我们可以开始监听事件
具有 online_users 键的全局集合用于保持每个用户的在线状态。因此,在新的连接上,用户 ID 将写入该集合
SADD online_users 1
在这里,我们将 ID 为 1 的用户添加到 online_users 集合中
之后,一条消息将广播给客户端,通知他们一个新用户加入了聊天。
PUBLISH message "{'serverId': 4132, 'type':'message', 'data': {'from': 1, 'date': 1615480369, 'message': 'Hello', 'roomId': '1:2'}}"
请注意,我们发送与消息类型和服务器 ID 相关的附加数据。服务器 ID 用于通过发送它们的服务器实例丢弃消息,因为它们连接到相同的 MESSAGES 频道。
序列化 JSON 的 type 字段对应于我们用于实时通信的实时方法(连接/断开连接/消息)。
data 字段是特定于方法的信息。在上面的示例中,它与新消息相关。
Redis 主要用作数据库,用于保存用户/消息数据以及在连接的服务器之间发送消息。
实时功能由 Socket.IO 处理,用于服务器-客户端消息传递。此外,每个服务器实例都订阅了发布/订阅的 MESSAGES 通道,并在消息到达时进行分发。请注意,服务器使用单独的事件流传输发布/订阅消息(由服务器发送事件处理),这是因为需要在 socket.io 信号之外运行发布/订阅消息循环。
聊天数据存储在各种键和各种数据类型中。用户数据存储在一个哈希集中,其中每个用户条目包含以下值
获取用户 HGETALL user:{id}。
HGETALL user:2
我们获取 ID 为 2 的用户的数据。
SMEMBERS user:2:rooms
这将返回 ID 为 2 的用户的房间 ID
示例
ZREVRANGE room:1:2 0 50
这将返回 ID 为 1 和 2 的用户之间私聊的 50 条消息,偏移量为 0。