【问题标题】:How to send user notifications using django-channels 2.0?如何使用 django-channels 2.0 发送用户通知?
【发布时间】:2019-01-07 00:24:45
【问题描述】:

我正在开发一个包含聊天室的聊天应用程序。每个房间有两个用户。一个用户可以在多个房间中,即一个用户有多个房间。现在他在一个房间里聊天。但他在另一个房间收到一条消息。我想将其他房间的消息通知给用户。我应该如何实施?

目前一个websocket连接建立为:ws://localhost:8000/chat/int<room_id>/

group_name 被命名为"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 蟒蛇3.6

【问题讨论】:

    标签: django django-models django-views django-channels


    【解决方案1】:

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

    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)
    

    【讨论】:

    • 通知应用看起来会相似吗?我们是否需要一个通知线程来引导传入的通知,或者我们可以在其他地方这样做吗?
    • 对于通知,您只需要两个模型:用户和通知。在connect 上,将范围设置为当前经过身份验证的用户。在 Notification 模型上设置post_save 信号,以触发消费者方法向通知对象的用户发送消息。
    • @Mint 的意思是在连接时将group_name 设置为用户。
    【解决方案2】:

    我做了类似的事情,你可以试试这样的:

    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']
                })
            })
    

    我可能误读了您的问题。也许更像:

    为每个用户创建一个唯一的 id 并将该值用作“聊天室”,然后发送每条消息,其中包含聊天室号码和应该发送到的用户号码。 Django 可以解释用户 id 并将消息发送到正确的频道,然后让 Javascript 将消息和房间号解释为正确的页面?

    这是一个有趣的想法

    【讨论】:

    • 它是django-channels 2.x。从 1.x 到 2.x 有一个重大变化。
    • 知道了......我想我可以把这个留给别人以防万一,我的坏笑
    【解决方案3】:

    (idea:)我开了两个socket:

    1. 一个用户正在发短信的当前房间
    2. 第二个用于聊天室列表(同时创建了一个隐藏的基础聊天室;更好的说法是:属于聊天室列表的频道层),

    然后在第一个解释频道(上图)中从任何用户收到的每条消息上,我都会向两个套接字发送正确的回复。

    此处的示例:chatroom.subtionary.com(只需单击一个聊天室并使用电子邮件进入) 它还重新排序聊天室列表和脉冲元素,并在其元素下写入每个聊天室的最后一条消息,还享受回复和删除选项!

    (我知道这是最懒惰的方式,但效果很好)

    【讨论】:

      猜你喜欢
      • 2017-01-12
      • 1970-01-01
      • 2021-06-15
      • 1970-01-01
      • 1970-01-01
      • 2017-06-09
      • 1970-01-01
      • 1970-01-01
      • 2019-08-06
      相关资源
      最近更新 更多