django-channels:跟踪 "rooms" 中的用户
django-channels: keeping track of users in "rooms"
TL;DR - 我如何维护每个房间的用户列表,以便我可以将该数据发送到前端以显示此参与者的列表房间。
我正在设计一个协作网络应用程序,它使用 django-channels 在浏览器和服务器之间进行 websocket 通信。一个房间可以由多个用户加入,每个用户都应该知道房间中的每个其他用户。我将如何使用 django-channels (v2) 实现这一目标?
我已经浏览了在线文档和一些示例项目,但是 none 其中添加了类似的功能。我也知道 django-channels-presence
,但该项目似乎没有得到积极维护,所以我并没有真正费心研究使用它的示例。
这是我到目前为止的想法:
- 对于每个房间,我在数据库中创建一个对象,这些对象可以跟踪房间中的用户。因此,例如,在 WS 消费者的 connect()
方法中,我可以调用 get_or_create_room()
和 room.add_participant(self.user_name)
(或从范围中获取它),在 disconnect()
方法中,我可以删除自己从房间。然而,这样做的问题是我最终可能会创造竞争条件?我认为?此外,由于我从 ORM 中获取对象,因此我必须确保每次在使用该对象之前我都必须从数据库中重新获取它,因为它可能(并且将会)很快变得过时。这似乎一点也不理想。
- 我能想到的另一种方法是将数据附加到消费者中的 self.channel_layer
,在那里我可以做类似 setattr(self.channel_layer, f'users_{room_id}', {})
的事情,并为每个进入和离开的用户维护这个字典。这又一次听起来不太安全,而且我没有看到任何人使用它,所以我不确定。
如有任何帮助,我们将不胜感激。我还想看看现有的应用程序是如何做到这一点的,如果有人能给我指点的话?
所以简而言之,无法为群组中的成员请求频道,因此您需要:
- 将一些信息写入数据库,并带有时间戳,以便您可以查看它是否旧
或
- 每(n 秒)通过频道组(带有用户 ID 的机器可读项)发送一条消息,然后您的消费者(或前端)可以维护用户列表并将其过滤为具有重发时间戳的用户。这里的缺点是可能需要几秒钟才能检测到聊天室中的所有用户。
您不能执行任何操作,例如写入 dict 或全局对象,因为这不会在所有使用者之间共享。
TL;DR - 我如何维护每个房间的用户列表,以便我可以将该数据发送到前端以显示此参与者的列表房间。
我正在设计一个协作网络应用程序,它使用 django-channels 在浏览器和服务器之间进行 websocket 通信。一个房间可以由多个用户加入,每个用户都应该知道房间中的每个其他用户。我将如何使用 django-channels (v2) 实现这一目标?
我已经浏览了在线文档和一些示例项目,但是 none 其中添加了类似的功能。我也知道 django-channels-presence
,但该项目似乎没有得到积极维护,所以我并没有真正费心研究使用它的示例。
这是我到目前为止的想法:
- 对于每个房间,我在数据库中创建一个对象,这些对象可以跟踪房间中的用户。因此,例如,在 WS 消费者的 connect()
方法中,我可以调用 get_or_create_room()
和 room.add_participant(self.user_name)
(或从范围中获取它),在 disconnect()
方法中,我可以删除自己从房间。然而,这样做的问题是我最终可能会创造竞争条件?我认为?此外,由于我从 ORM 中获取对象,因此我必须确保每次在使用该对象之前我都必须从数据库中重新获取它,因为它可能(并且将会)很快变得过时。这似乎一点也不理想。
- 我能想到的另一种方法是将数据附加到消费者中的 self.channel_layer
,在那里我可以做类似 setattr(self.channel_layer, f'users_{room_id}', {})
的事情,并为每个进入和离开的用户维护这个字典。这又一次听起来不太安全,而且我没有看到任何人使用它,所以我不确定。
如有任何帮助,我们将不胜感激。我还想看看现有的应用程序是如何做到这一点的,如果有人能给我指点的话?
所以简而言之,无法为群组中的成员请求频道,因此您需要:
- 将一些信息写入数据库,并带有时间戳,以便您可以查看它是否旧
或
- 每(n 秒)通过频道组(带有用户 ID 的机器可读项)发送一条消息,然后您的消费者(或前端)可以维护用户列表并将其过滤为具有重发时间戳的用户。这里的缺点是可能需要几秒钟才能检测到聊天室中的所有用户。
您不能执行任何操作,例如写入 dict 或全局对象,因为这不会在所有使用者之间共享。