从视图访问消费者以通过 WebSocket (Django-Channelsv2.2 & DRF) 将 api 接收的数据推送给用户

Posted

技术标签:

【中文标题】从视图访问消费者以通过 WebSocket (Django-Channelsv2.2 & DRF) 将 api 接收的数据推送给用户【英文标题】:Access Consumer from View to push api-received data to User via WebSocket (Django-Channelsv2.2 & DRF) 【发布时间】:2019-11-04 23:27:11 【问题描述】:

我发现自己很难找到一种方法将数据从 View(APIView Django-rest-framework)或分布式任务(直接 Celery/RabbitMQ)推送到消费者(Django Channels v.2.2)

我非常感谢任何允许我从 View 访问消费者的代码示例,因为触发器本身是输入设备,而不是 Web,所以我可以从中进行 API 调用,所以我需要连接器。

Django Channels v.2.2,DjangoChannelsRestFramework,这里描述的大部分案例:https://channels.readthedocs.io/en/latest/community.html 以及相关问题@***

consumers.py

class BasicConsumer(AsyncConsumer):
    async def websocket_connect(self, event):
        print('connected', event)
        await self.send(
            "type": "websocket.accept"
        )
        # await self.send(
        #     "type": "websocket.send",
        #     "text": "Hello world"
        # )

    async def websocket_receive(self, event):
        print('receive', event)
        front_text = event.get('text', None)
        if front_text is not None:
            loaded_dict_data = json.loads(front_text)
            msg = loaded_dict_data.get('message')
            print(msg)
            user = self.scope['user']

            if user.is_authenticated:
                username = user.username
            myResponse = 
                'message': msg,
                'username': username
            
            await self.send(
                "type": "websocket.send",
                "text": json.dumps(myResponse)
            )

    async def websocket_disconnect(self, event):
        print('disconnect', event)

    @database_sync_to_async
    def get_thread(self, user, other_username):
        return Thread.objects.get_or_new(user, other_username)[0]

views.py

class BasicView(APIView):
    def post(self, request):
        serializer = BasicViewSerializer(data=request.data)
        if serializer.is_valid():
           triggerConsumer(serializer.validated_data)

【问题讨论】:

【参考方案1】:

我认为最好定义一个通道名称并向其发送数据。

from asgiref.sync import async_to_sync
async_to_sync(channel_layer.send)("channel_name", ...)

您可以在此处查看完整文档doc

【讨论】:

谢谢你,奥米德。你以前做过吗?我可以请您草绘将序列化程序的验证数据从示例发送到 BasicConsumer 方法之一的示例代码吗? @Aleks_Saint 您需要添加一个单独的消费者方法来处理序列化程序数据。基本的消费者方法已经有特定的用途,所以你不应该为此使用它们。再次检查他链接的文档页面

以上是关于从视图访问消费者以通过 WebSocket (Django-Channelsv2.2 & DRF) 将 api 接收的数据推送给用户的主要内容,如果未能解决你的问题,请参考以下文章

向非 Stomp/Websocket 消费者发送消息

ListView:如何从列表中访问视图以更改背景颜色?

如何从控制器或其他组件/服务访问 websocket?

从rabbitmq消费消息并通过其客户端连接转发它们的“扭曲”方式是啥?

从网络选项卡捕获 Websocket 消息

如何通过 Django 通道 WebSocket 传递请求并调用 Django 视图