如何限制django频道房间里的客户数量

rbl8hiat  于 2023-03-04  发布在  Go
关注(0)|答案(2)|浏览(133)

我希望限制在一个房间的用户数量为2,因为我正在做一个插座游戏,两个玩家可以玩一个井字游戏或连接-4游戏,所以我试图找到一些方法来限制只有2个玩家在一个房间。
下面是我的网站comsumers.py

from channels.generic.websocket import WebsocketConsumer
from asgiref.sync import async_to_sync
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
        print(self.room_group_name)
        async_to_sync(self.channel_layer.group_add)(
            self.room_group_name,
            self.channel_name
        )

        self.accept()

我已经从这个问题中删除了一些不太必要的方法

t5fffqht

t5fffqht1#

您必须在项目中创建一个room模型,并将连接的用户保存到其中,然后您可以在connect方法中添加一个validation,如下所示:

def connect(self):
    self.room_name = self.scope['url_route']['kwargs']['room_code']
    
    self.room = Room.objects.get(code=self.room_name)
    if self.room.connected_user >= 2:
        return self.close()
    else:
        self.room.connected_user = self.room.connected_user + 1
        self.room.save(update_fields=['connected_user'])

        self.room_group_name = 'room_%s' % self.room_name
        print(self.room_group_name)
        async_to_sync(self.channel_layer.group_add)(
            self.room_group_name,
            self.channel_name
        )

        self.accept()

def disconnect(self):
    ...
    self.room.connected_user = self.room.connected_user - 1 
    self.room.save(update_fields=['connected_user'])
  • 额外:

当然,您可以使用F()函数,并在connectdisconnect中使您的性能更好(当许多用户试图同时连接时非常有用)

tpgth1q7

tpgth1q72#

如果使用RedisChannelLayer,请使用下一种方法扩展它们(决定取决于RedisChannelLayer.group_add方法):

class ExtendedRedisChannelLayer(RedisChannelLayer):

    async def count_group_channels(self, group):
        assert self.valid_group_name(group), "Group name not valid"
        key = self._group_key(group)
        connection = self.connection(self.consistent_hash(group))
        # Discard old channels based on group_expiry
        await connection.zremrangebyscore(
            key, min=0, max=int(time.time()) - self.group_expiry
        )

        return await connection.zcount(key, 0, -1)

在设置中定义:

CHANNEL_LAYERS = {
    "default": {
        "BACKEND": "your_path.ExtendedRedisChannelLayer",
        ...
    }
}

在消费者体内使用:

channels_count = async_to_sync(self.channel_layer.count_group_channels)(self.room_group_name)

相关问题