在 Django Channels 中创建等待队列?

Posted

技术标签:

【中文标题】在 Django Channels 中创建等待队列?【英文标题】:Creating a waiting queue in Django Channels? 【发布时间】:2020-03-21 20:11:50 【问题描述】:

我目前正在使用通道在我的 Django 应用程序上开发“等待队列”应用程序。我有一个使用 Redis 处理组内连接的通道层。我还在我的数据库中使用一个模型来跟踪队列中的用户数量。我的问题是是否有一种更简单、更可扩展的方式。以后会有什么问题吗?

class ChatConsumer(AsyncWebsocketConsumer):

    @database_sync_to_async
    def get_waiting_room(self):
        return WaitingRoom.objects.all().count()

    @database_sync_to_async
    def add_to_waiting_room(self, name):
        return WaitingRoom.objects.create(name=name)

    @database_sync_to_async
    def remove_from_waiting_room(self, name):
        return WaitingRoom.objects.filter(name=name).delete()

    async def connect(self):
        self.waiting_list = 'waiting_list'

        await self.channel_layer.group_add(
            self.waiting_list, self.channel_name)

        await self.accept()

    async def receive(self, text_data):
        self.text_data = json.loads(text_data)

        await self.add_to_waiting_room(self.text_data['user'])

        users = await self.get_waiting_room()

        await self.channel_layer.group_send(self.waiting_list, 
            'type': 'user_list',
            'users': str(users)
        )

    async def disconnect(self, close_code):

        await self.remove_from_waiting_room(name=self.text_data['user'])
        await self.channel_layer.group_discard(
            self.waiting_list,
            self.channel_name)

        users = await self.get_waiting_room()

        await self.channel_layer.group_send(self.waiting_list, 
            'type': 'user_list',
            'users': str(users)
        )

    async def user_list(self, event):
        users = event['users']

        await self.send(text_data=users)

当用户连接时,他们被添加到channel_layer(Redis)中的一个组并接受连接,当我的用户单击一个按钮时,它向通道发送请求并将它们添加到等候室(我的Django模型),在断开连接时,它会删除模型实例并向通道发送一个带有更新的“用户”计数的信号。

有没有更简单的方法来做到这一点?这种方法会在路上造成任何障碍吗?

提前致谢。

【问题讨论】:

我和你在同一条路上,我将使用 Django 和 Channels 实现类似的案例。你有什么要给我的吗?谢谢你。 @刘易斯 @SilentHG 这并不是那么简单,但是,我只是将用户的位置存储在数据库中,并确保始终进行硬数据库查询。一旦他们离开队列,我会发送其他人在队列中的位置并在客户端处理它。 【参考方案1】:

浏览器并不总是干净地关闭 websocket 连接,所以我认为 disconnect() 有可能永远不会被触发。因此,您可能会在数据库中获得陈旧的数据,或者连续调用 .connect() 两次,从而导致完整性错误。

【讨论】:

您有其他解决方案吗?

以上是关于在 Django Channels 中创建等待队列?的主要内容,如果未能解决你的问题,请参考以下文章

VBA - 如何在数组中创建队列? (FIFO)先进先出

在 Anylogic 中创建已在队列中的代理集合

我们如何在 django 中创建异步 API?

在 PyTorch 中创建具有多个通道的简单 1D CNN

Win32,等待主消息队列中的线程?

如何在 Dart 中创建 StreamTransformer?