【问题标题】:Send data to websocket via signals通过信号向 websocket 发送数据
【发布时间】:2021-06-12 05:55:52
【问题描述】:

我希望你们都做得很好。我一直在尝试创建一个通知系统,该系统将通过数据库中的 post_save 信号将消息推送到 websocket。我有一个创建通知的通知模型,我想在向适当的用户创建通知时推送通知,非常感谢任何帮助。

信号.py

def send_message(event):
    '''
    Call back function to send message to the browser
    '''
    message = event['text']
    channel_layer = channels.layers.get_channel_layer()
    # Send message to WebSocket
    print("Sending message to websocket")
    async_to_sync(channel_layer.send)(text_data=json.dumps(
        message
    ))

@receiver(post_save,sender=Notification)
def notification_handler(sender,instance,created,*args,**kwargs):
    message={
        'text':instance.text
    }
    print(message)
    user=str(instance.to.pk)
    groupname=f"user_{user}"
    channel_layer = channels.layers.get_channel_layer()
    async_to_sync(channel_layer.group_send)(
        groupname,
        {
            'type': 'send_message',
            'text': message
        }
    )

这就是我的 consumer.py 的样子

consumer.py

class NotificationConsumer(AsyncWebsocketConsumer):
    async def websocket_connect(self,event):
        print("connected",event)
        self.channel_layer=channels.layers.get_channel_layer()
        self.user = self.scope['url_route']['kwargs']['user_id']
        self.group_name =f"user_{self.user}"
        await self.channel_layer.group_add(
            self.group_name,
            self.channel_name
        )

        await self.accept()
    
    async def websocket_disconnect(self,event):
        print(event,"closed")    


【问题讨论】:

    标签: python django asynchronous django-channels django-signals


    【解决方案1】:

    通过在相关模型的 post_save 上使用以下代码创建通知系统解决了该问题。

    consumers.py

    class NotificationConsumer(AsyncWebsocketConsumer):
        
        async def websocket_connect(self,event):
            print("connected",event)
            self.channel_layer=channels.layers.get_channel_layer()
            self.user = self.scope['url_route']['kwargs']['user_id']
            
            self.group_name =f"user_{self.user}"
            print(self.group_name)        
    
            await self.channel_layer.group_add(
                self.group_name,
                self.channel_name
            )
    
            await self.accept()
            user=self.scope['user']
            
            unread_notifications= await self.get_unread_notifications(user)
            unread_notifications['notification_type']="group"
    
            await self.channel_layer.group_send(
                        self.group_name,
                        {
                            'type': 'send_notification',
                            'text': unread_notifications
                        }
                    )
    
        #To fetch unread notifications which have been recorded while the user was offline
        @staticmethod
        @receiver(post_save,sender=Notification)
        def notification_handler(sender,instance,created,*args,**kwargs):
            if instance.read !=1:
                message={
                    'notification_type':"single",
                    'text':instance.text,
                    'id':instance.pk_object,
                    "type":instance.Type,
                    "timestamp":str(instance.timestamp),
                    "by":ProfileSerializer(instance.by).data
                }
                print("Inside the notification trigger",message)
                user=str(instance.to.user.pk)
                groupname=f"user_{user}"
                channel_layer = channels.layers.get_channel_layer()
                async_to_sync(channel_layer.group_send)(
                            groupname,
                            {
                                'type': 'send_notification',
                                'text': message
                            }
                        )
            
        async def send_notification(self, event):
            print("inside send notification")
            await self.send(text_data=json.dumps({
                'type': 'websocket.send',
                'text': event['text']
            }))
        @database_sync_to_async
        def get_unread_notifications(self, user):
            return Notification.objects.get_unread(user)
    
    

    models.py

    @receiver(post_save,sender=Connect)
    
    def connect_handler(sender,instance,created,*args,**kwargs):
        from django.apps import apps
        Notification= apps.get_model("notifications","Notification")
        if created and instance.confirmed == 0:     
            print("inside trigger")
            notification=Notification.objects.create(
                to=instance.user2,
                Type="connection",
                text=f"{instance.user1} sent you a connection request",
                by=instance.user1,
                pk_object=instance.user1.pk
            )
    @receiver(post_save,sender=Like)
    
    def like_handler(sender,instance,created,*args,**kwargs):
        from django.apps import apps
        Notification= apps.get_model("notifications","Notification")
        if created:
            if instance.idea != None:
                changed=instance.idea
                changed_type="Idea"
                object_id=instance.idea.pk
                element=instance.idea
            else:
                changed=instance.post
                changed_type="Post"
                object_id=instance.post.pk
                element =instance.post
            if instance.Liked_by != element.posted_by:
                notification=Notification.objects.create(
                    to=changed.posted_by,
                    Type=changed_type,
                    text=f"{instance.Liked_by.user.username} Liked your {changed_type}",
                    by=instance.Liked_by,
                    pk_object=object_id
                )
    

    【讨论】:

      猜你喜欢
      • 2020-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-14
      • 1970-01-01
      相关资源
      最近更新 更多