You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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,避免已配对用户被重复加入队列
  • 用户加入队列逻辑:当用户触发「进入随机匹配」操作时,先校验用户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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 16:15:03