Как отправлять уведомления пользователям с помощью django-channels 2.0?

Я работаю над приложением чата, в котором есть Комнаты. В каждой комнате по два пользователя. Пользователь может находиться в нескольких комнатах, т. Е. У пользователя есть несколько комнат. А теперь он болтает в одной комнате. Но он получает сообщение в другой комнате. Я хочу уведомить пользователя о сообщении из другой комнаты. Как мне это реализовать?

В настоящее время соединение с веб-сокетом устанавливается как: ws://localhost:8000/chat/int<room_id>/

И имя_группы называется "room"+room_id. и пока у меня есть:

async def connect(self):
    room_id = self.scope['url_route']['kwargs']['room_id']
    await self.channel_layer.group_add(
            "room"+room_id,
            self.channel_name
        )
    await self.accept()

async def receive(self, text_data):
    await self.channel_layer.group_send(
        self.room_name,
        {
            'type': 'chat_message',
            'message': json.loads(text_data)
        }
    )
async def chat_message(self, event):
    await self.send(text_data=json.dumps({
        'message': event['message']
    }))

Django 2.x django-каналы 2.x python 3.6


person whitehat    schedule 30.07.2018    source источник


Ответы (3)


Вам нужно как минимум две модели Message, MessageThread. Когда пользователь подключается к сокету, канал добавляется к каждой группе потоков, в которую входит пользователь. Вы также должны добавить channel_name в сеанс пользователя.

messaging/models.py

class MessageThread(models.Model):
    title = models.CharField()
    clients = models.ManyToManyField(User, blank=True)

class Message(models.Model):
    date = models.DateField()
    text = models.CharField()
    thread = models.ForeignKey('messaging.MessageThread', on_delete=models.CASCADE)
    sender = models.ForeignKey(User, on_delete=models.SET_NULL)

chat/consumers.py

class ChatConsumer(WebSocketConsumer):
    def connect(self):
        if self.scope['user'].is_authenticated:
            self.accept()
            # add connection to existing groups
            for thread in MessageThread.objects.filter(clients=self.scope['user']).values('id'):
                async_to_sync(self.channel_layer.group_add)(thread.id, self.channel_name)
            # store client channel name in the user session
            self.scope['session']['channel_name'] = self.channel_name
            self.scope['session'].save()

    def disconnect(self, close_code):
        # remove channel name from session
        if self.scope['user'].is_authenticated:
            if 'channel_name' in self.scope['session']:
                del self.scope['session']['channel_name']
                self.scope['session'].save()
            async_to_sync(self.channel_layer.group_discard)(self.scope['user'].id, self.channel_name)
person bdoubleu    schedule 02.08.2018
comment
Будет ли похоже приложение для уведомлений? Нужен ли нам поток уведомлений для направления входящих уведомлений или мы можем сделать это где-нибудь еще? - person Mint; 15.10.2018
comment
Для уведомлений вам понадобятся всего две модели: Пользователь и Уведомление. На connect установите область для текущего аутентифицированного пользователя. Настройте сигнал post_save в своей модели уведомлений, чтобы вызвать метод потребителя для сообщения пользователю объекта уведомления. - person bdoubleu; 15.10.2018
comment
@Mint означает установить group_name для пользователя при подключении. - person bdoubleu; 15.10.2018

Я делаю нечто подобное, вы можете попробовать что-то вроде этого:

connect(message):
    // however you get your chatroom value from the socket
    Group("%s" % chatroom).add(message.reply_channel)

message(message):
    message = json.loads(message.content['text'])
    chatroom = message['chatroom']  
    Group("%s" % chatroom).send({
            "text": json.dumps({
                "id": "newuser",
                "username": message['username'],
                "message": message['message']
            })
        })

Возможно, я неправильно понял твой вопрос. Может быть, что-то вроде:

Создайте уникальный идентификатор для каждого пользователя и используйте это значение в качестве «чата», а затем отправьте каждое сообщение с номером чата и номером пользователя, на который оно должно перейти. Django может интерпретировать идентификатор пользователя и отправить сообщение на правильный канал, а затем заставить Javascript интерпретировать ему сообщение и номер комнаты, чтобы перенаправить их на нужную страницу?

Это интересная идея

person ThatCampbellKid    schedule 31.07.2018
comment
Это django-channels 2.x. Произошло серьезное изменение с 1.x на 2.x. - person whitehat; 01.08.2018
comment
Попался ... Думаю, я могу оставить это другим на всякий случай, мой плохой лол - person ThatCampbellKid; 01.08.2018

(идея :) Я открыл два сокета:

  1. один для текущей комнаты, в которой пользователь пишет текстовые сообщения
  2. второй - для списка чатов (также создается скрытая базовая чат-комната; лучше сказать: слой канала, принадлежащий списку чатов),

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

пример здесь: chatroom.subtionary.com (просто нажмите на один чат и введите адрес электронной почты) он также изменит порядок Список чатов и пульсирующий элемент, а также напишите последнее сообщение каждого чата под его элементом, также наслаждайтесь вариантами ответа и удаления !!

(Я знаю, что это самый ленивый способ, но он работает хорошо)

person Mohammad Aqajani    schedule 11.09.2019