django-channels: отслеживание пользователей в "комнатах"
TL;DR - Как мне вести список пользователей в каждой комнате, чтобы я мог отправлять эти данные во внешний интерфейс, чтобы отобразить список участников в этой комнате.
Я разрабатываю совместное веб-приложение, которое использует django-каналы для связи через веб-сокеты между браузером и сервером. К комнате может присоединиться более одного пользователя, и каждый пользователь должен знать обо всех остальных пользователях в комнате. Как мне добиться этого с помощью django-channels (v2)?
Я уже просмотрел документацию и несколько примеров проектов, доступных в Интернете, но ни один из них не добавил аналогичных функций. Я также знаю оdjango-channels-presence
но похоже, что проект не поддерживается активно, поэтому я особо не утруждал себя изучением примеров с его использованием.
Вот что я до сих пор придумал:
- Для каждой комнаты я создаю объект в базе данных, и эти объекты могут отслеживать пользователей, находящихся в комнате. Так, например, в потребительской сети WSconnect()
метод, я мог бы сделать get_or_create_room()
позвони и room.add_participant(self.user_name)
(или получить это из области видимости) и в disconnect()
методом я мог удалиться из комнаты. Однако проблема в том, что я могу создать условия гонки? Я думаю? Кроме того, поскольку я получаю объекты из ORM, я должен убедиться, что каждый раз перед использованием этого объекта мне нужно повторно получать его из БД, потому что он может (и будет) быстро устареть. Это совсем не кажется идеальным.
- Другой способ, который я могу придумать, - это прикрепление данных к self.channel_layer
в потребителе, где я могу сделать что-то вроде setattr(self.channel_layer, f'users_{room_id}', {})
и поддерживать этот словарь для каждого входящего и выходящего пользователя. Это снова звучит не очень безопасно, и я не видел, чтобы кто-то использовал это, поэтому я не уверен.
Любая помощь по этому поводу будет оценена. Я также хотел бы увидеть, как это делают существующие приложения, если кто-нибудь может указать мне на одно?
1 ответ
Короче говоря, нет возможности запросить каналы для участников группы, поэтому вам нужно:
- Запишите некоторую информацию в базу данных с отметкой времени, чтобы вы могли видеть, устарела ли она
или
- отправлять сообщение каждые (n секунд) по группе каналов (машиночитаемый элемент с идентификатором пользователя), тогда ваши потребители (или интерфейс) могут поддерживать список пользователей и фильтровать его для тех, у которых есть повторно отправленная временная метка. Недостатком здесь является то, что обнаружение всех пользователей в чате может занять несколько секунд.
Вы не можете делать ничего подобного записи в dict или глобальный объект, так как это не является общим для всех потребителей.