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

如何限制Django Channels房间内的客户端连接数量

Django Channels 单房间用户数限制为2的实现方案

核心实现逻辑

在WebSocket连接建立阶段先校验当前房间的已接入人数,仅在人数不足2时允许接入,同时在连接断开时同步更新人数计数,通过原子操作避免并发竞态问题。

前置依赖

确保你已在settings.py中配置了缓存(推荐使用Redis缓存,可与Channels的Channel Layer共用Redis实例),示例配置参考:

# settings.py 新增缓存配置
CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379/1",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        }
    }
}

修改 consumers.py 代码

from channels.generic.websocket import WebsocketConsumer
from asgiref.sync import async_to_sync
from django.core.cache import cache
import json


class GameRoom(WebsocketConsumer):

    def connect(self):
        self.room_name = self.scope['url_route']['kwargs']['room_code']
        self.room_group_name = 'room_%s' % self.room_name
        # 按房间生成唯一的缓存计数键
        self.room_count_key = f"room_user_count_{self.room_name}"

        # 原子操作增加计数,首次调用自动初始化为1
        current_count = cache.incr(self.room_count_key)
        # 人数超过2则回退计数、拒绝连接
        if current_count > 2:
            cache.decr(self.room_count_key)
            # 自定义状态码4403表示房间已满,前端可捕获该状态做对应提示
            self.close(code=4403)
            return

        # 人数校验通过,执行原有加组逻辑
        async_to_sync(self.channel_layer.group_add)(
            self.room_group_name,
            self.channel_name
        )
        self.accept()

    def disconnect(self, close_code):
        # 连接断开时减少房间人数计数
        current_count = cache.decr(self.room_count_key)
        # 房间无人时删除缓存键节省空间
        if current_count <= 0:
            cache.delete(self.room_count_key)
        # 执行原有退组逻辑
        async_to_sync(self.channel_layer.group_discard)(
            self.room_group_name,
            self.channel_name
        )

Redis的incr/decr是原子操作,可避免多个用户同时接入时的计数错误问题

备选方案(无额外缓存依赖)

如果你使用Redis作为Channel Layer,也可以直接查询当前组内的Channel数量判断人数,无需额外配置缓存:

# connect方法中人数校验逻辑替换为以下代码即可
channel_list = async_to_sync(self.channel_layer.group_channels)(self.room_group_name)
if len(channel_list) >= 2:
    self.close(code=4403)
    return

注意:该方案依赖Channel Layer的内部API,不同版本的Channels可能存在兼容性问题,生产环境更推荐使用缓存计数方案。

内容的提问来源于stack exchange,提问作者Aryan Gupta

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 08:06:01