如何使用Django在后端维护用户列表实现随机聊天配对功能
Django Channels 随机聊天配对功能实现方案
核心设计思路
我们使用全局等待队列存储正在等待随机配对的用户,配对时原子取出队首2名用户,配对完成后自动将二人移出队列,配合状态标记避免用户重复参与配对。优先推荐使用Redis实现队列,可天然适配Django Channels的异步场景、避免并发冲突,性能远高于数据库实现。
具体实现步骤
方案1:Redis实现(推荐)
- 依赖准备:安装
django-redis包,在项目配置文件中将Redis设为缓存后端,可直接复用Channels已配置的Redis实例。 - 定义全局存储规则:
- 用Redis的List结构存储等待队列,固定key为
random_chat_waiting_list - 用Redis的Set结构存储已配对成功的用户ID,固定key为
random_chat_matched_users,避免已配对用户被重复加入队列
- 用Redis的List结构存储等待队列,固定key为
- 用户加入队列逻辑:当用户触发「进入随机匹配」操作时,先校验用户ID不在
random_chat_matched_users集合中,校验通过后用rpush命令将用户ID推入等待队列尾部,随后立即执行配对逻辑。 - 原子配对逻辑代码示例:
from django_redis import get_redis_connection def run_random_match(): redis_conn = get_redis_connection("default") # 原子取出前2名用户,避免多请求并发冲突 user_a = redis_conn.lpop("random_chat_waiting_list") user_b = redis_conn.lpop("random_chat_waiting_list") # 若队列仅剩余1人,将取出的用户塞回队列 if not user_b: if user_a: redis_conn.lpush("random_chat_waiting_list", user_a) return None user_a_id = user_a.decode() user_b_id = user_b.decode() # 将二人标记为已配对 redis_conn.sadd("random_chat_matched_users", user_a_id, user_b_id) return (user_a_id, user_b_id)
- 配对后处理:拿到配对成功的两个用户ID后,生成唯一的随机聊天房间ID,通过Channels Group向两个用户推送配对成功通知,引导双方进入对应房间聊天。
- 退出逻辑:用户主动取消匹配、断开WebSocket连接或结束随机聊天时,自动将用户ID从等待队列和已配对集合中移除,若用户已有配对对象,同时向对方推送「对方已断开」通知。
方案2:数据库实现(小规模场景适用)
如果项目规模很小,不想引入Redis依赖,可以用Django模型实现队列,配合数据库事务加锁避免并发问题:
- 定义等待队列模型:
from django.db import models from django.contrib.auth import get_user_model User = get_user_model() class RandomChatWaitingUser(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="random_chat_waiting") join_at = models.DateTimeField(auto_now_add=True) class Meta: ordering = ["join_at"]
- 配对逻辑代码示例:
from django.db import transaction @transaction.atomic def run_db_match(): # 加行锁避免并发时出现重复配对问题 waiting_users = RandomChatWaitingUser.objects.select_for_update().all()[:2] if len(waiting_users) < 2: return None user_a_id = waiting_users[0].user.id user_b_id = waiting_users[1].user.id # 二人移出等待队列 waiting_users.delete() return (user_a_id, user_b_id)
优化建议
- 可给等待队列的用户加超时机制,比如等待超过5分钟未配对成功自动移出队列,给用户推送超时通知
- 可以添加匹配过滤逻辑,比如按兴趣、地域标签筛选配对对象,只需在取出用户时增加对应判断即可
- 分布式部署场景下仅需保证所有服务节点连接同一个Redis实例,配对逻辑无需修改
内容的提问来源于stack exchange,提问作者Deepanshu verma
相关产品推荐
相关产品推荐

