如何使用django-channels 2.0发送用户通知?

问题描述:

我正在使用具有房间功能的聊天应用程序。每个房间有两个用户。一个用户可以在多个房间中,即一个用户有多个房间。现在他正在一个房间里聊天。但是他在另一个房间里收到一条消息。我想将其他房间的消息通知给用户。我应该如何实现呢?

I am working on a chat app that has Rooms. Each room has two users. A user can be in multiple rooms i.e, a user has multiple rooms. And now he is chatting in one room. But he receives a message in another room. I would like to notify about the message from other room to the user. How should I implement this?

当前,Websocket连接已建立为: ws:// localhost:8000 / chat / int< room_id> /

Currently a websocket connection is established as: ws://localhost:8000/chat/int<room_id>/

并且group_name命名为 room + room_id 。到目前为止,我有:

And the group_name is named as "room"+room_id. and So far I have:

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-channels 2.x
python 3.6

Django 2.x django-channels 2.x python 3.6

您至少需要两个模型 Message MessageThread 。当用户连接到套接字时,会将通道添加到用户所在的每个线程组中。还必须将channel_name添加到用户会话中。

You need at least two models Message, MessageThread. When the user connects to the socket the channel is added to each thread group that the user is included in. You also have to add the channel_name to the user session.

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)