Django Каналы - функция приемника вызывается несколько раз в зависимости от количества открытых веб-сокетов - PullRequest
0 голосов
/ 08 мая 2020

Я не понимаю поведения Django каналов 2.4.0. Когда открыто несколько веб-сокетов, функция приемника вызывается так часто, как открыты веб-сокеты.

Вот минимальный код из хорошо известного примера чата из документации каналов

    # Receive message from WebSocket
async def receive(self, text_data):
    text_data_json = json.loads(text_data)
    message = text_data_json['message']

    # Send message to room group
    await self.channel_layer.group_send(
        self.room_group_name,
        {
            'type': 'chat_message',
            'message': message
        }
    )

# Receive message from room group
async def chat_message(self, event):
    print(event) # this is called as often as sockets are open
    message = event['message']
    # Send message to WebSocket
    await self.send(text_data=json.dumps({
        'message': message
    }))

Проблема становится серьезной, когда я хочу делать logi c вещи в базе данных, запускаемые из функция приемника. Затем действия начинают выполняться несколько раз в зависимости от того, сколько веб-сокетов открыто. Есть идеи, что мне здесь не хватает?

1 Ответ

1 голос
/ 09 мая 2020

Django каналов создает один экземпляр вашего класса Consumer для каждого открытого подключения к веб-сокету.

Идея group_send состоит в том, чтобы вызвать ту функцию, которая соответствует вашему значению type. Эта функция вызывается для каждого экземпляра потребителя, который подписался (group_add) на эту группу.

Если у вас есть работа, которая не зависит от отдельных подключений (например, идентификатор пользователя может отличаться для каждого подключения), тогда выполните это перед вашим group_send сообщением.

Так что, если вам нужно запросить ваш db, сделайте это до вашего group_send, затем сериализуйте результаты и отправьте их через уровень канала как часть вашего сообщения group_send.

Однако, если ваш запрос к БД должен учитывать подписанного пользователя (то есть отфильтровать информацию, которую им не разрешено видеть), вам нужно сделать это в обработчике chat_message, и он будет вызываться для каждого подписанного соединения . В качестве альтернативы вы можете выполнить запрос перед group_send, который предоставляет необходимую информацию, чтобы в вашем chat_message вы могли просто проверить сообщение, чтобы определить, можно ли его отправить пользователю.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...