@aLap

Правильный способ использования websockets в Django?

Есть вэб-интерфейс, написанный на Django 4, нужно сделать так, чтобы при поступлении post запроса от сторонней системы у определенного пользователя (его идентификатор есть в этом post) всплывало некое сообщение.
Принять запрос от сторонней системы/обработать его - всё ок, вопрос в том, как отправить сообщение конкретному consumer'у. В документации/примерах, которые я находил, сообщения отправляются на некие запросы от потребителя (чаты/игры), в моём же случае, от потребителя кроме connect ничего не ожидается. Вопрос, скорее в том, как при помощи channels обращаться к потребителю в одностроннем порядке.
  • Вопрос задан
  • 100 просмотров
Решения вопроса 1
@aLap Автор вопроса
В общем, разобрался самостоятельно, вот что вышло, может, кому-то пригодится:

from channels.generic.websocket import WebsocketConsumer
from asgiref.sync import async_to_sync
import json


class WsConsumer(WebsocketConsumer):
    def connect(self):
        self.accept()
        self.user_id = self.scope['url_route']['kwargs']['user_id'] # ID пользователя приходит как часть url
        async_to_sync(self.channel_layer.group_add)( # Добавляем пользователя в собственную группу
            str(self.user_id),                            # Таким образом, сообщения будут во всех табах
            self.channel_name
        )

    def disconnect(self, close_code):
        pass

    def send_message(self, event):  # Функция отправки должна быть внутри consumer'а
        message = event['message']
        message['type'] = 'message'
        self.send(json.dumps(message))


def send_to_group(group_name, message): # А эта функция за пределами класса
    from channels.layers import get_channel_layer #  и может быть вызвана откуда угодно в рамках проекта
    from asgiref.sync import async_to_sync
    message = {'message': message}
    channel_layer = get_channel_layer()

    async_to_sync(channel_layer.group_send)(group_name, {"type": "send.message", # значение type должно совпадать с именем функции отправки внутри класса, только с точкой вместо подчеркивания. Такая логика.
                                                         "message": message})
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы