簡體   English   中英

Django 渠道消費者收不到數據

[英]Django channels consumer not receiving data

我正在嘗試編寫一個 websocket 消費者,它在客戶端仍連接到 websocket 時獲取所有未讀通知以及正在創建的所有通知。

我能夠連接到消費者,它向我顯示所有活動通知。 問題是當它們被創建並從模型的保存方法發送時,它沒有向我顯示新通知。

消費者.py

class NotificationConsumer(WebsocketConsumer):
    def get_notifications(self, user):
        new_followers = NotificationSerializer(Notification.objects.filter(content=1), many=True)

        notifs = {
            "new_followers": new_followers.data
        }

        return {
            "count": sum(len(notif) for notif in notifs.values()),
            "notifs": notifs
        }

    def connect(self):
        user = self.scope["user"]

        if user:
            self.channel_name = user.username
            self.room_group_name = 'notification_%s' % self.channel_name

            notification = self.get_notifications(self.scope["user"])
            print("Notification", notification)

            self.accept()
            return self.send(text_data=json.dumps(notification))
        
        self.disconnect(401)
    
    async def disconnect(self, close_code):
        await self.channel_layer.group_discard(
            self.room_group_name,
            self.channel_name
        )
    
    async def receive(self, text_data):
        text_data_json = json.loads(text_data)
        count = text_data_json['count']
        notification_type = text_data_json['notification_type']
        notification = text_data_json['notification']
        print(text_data_json)

        await self.channel_layer.group_send(
            self.room_group_name,
            {
                "type": "receive",
                "count": count,
                "notification_type": notification_type,
                "notification": notification
            }
        )

模型.py

class Notification(models.Model):
    content = models.CharField(max_length=200, choices=NOTIFICATION_CHOICES, default=1)
    additional_info = models.CharField(max_length=100, blank=True)
    seen = models.BooleanField(default=False)
    users_notified = models.ManyToManyField("core.User", blank=True)
    user_signaling = models.ForeignKey("core.User", on_delete=models.CASCADE, related_name="user_signaling")

    def save(self, *args, **kwargs):
        if self._state.adding:
            super(Notification, self).save(*args, **kwargs)

        else:
            notif = Notification.objects.filter(seen=False)
            data = {
                "type": "receive",
                "count": len(notif),
                "notification_type": self.content,
                "notification": self.additional_info
            }

            channel_layer = get_channel_layer()
            for user in self.users_notified.all():
                async_to_sync(channel_layer.group_send(
                        f"notification_{user.username}",
                        data
                    )
                )
                print(channel_layer)

我正在檢查self._state.adding ,因此它只會在創建users_notified后添加 users_notified 時發送 websocket 消息。

示例用例:

notif = Notification.objects.create(
      content=1, 
      user_signaling=user,
      additional_info=f"{user.username} just followed you!"
)
notif.users_notified.add(other_user)
notif.save()

通常對我有用的是使用信號,在你的情況下,你可以使用 post_save 信號而不是覆蓋 model save()。

channel_layer = get_channel_layer()


@receiver(post_save, sender=Notification)
def notification_on_create(sender, instance, created, **kwargs) -> None:
    _, _ = sender, kwargs
    if created:
        return None
    notif = Notification.objects.filter(seen=False)
    data = {
                "type": "receive",
                "count": len(notif),
                "notification_type": instance.content,
                "notification": instance.additional_info
            }
    for user in self.users_notified.all():
        async_to_sync(channel_layer.group_send(
                f"notification_{user.username}", data))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM