Django Channels-不断从服务器向客户端发送数据 [英] Django Channels - constantly send data to client from server

查看:864
本文介绍了Django Channels-不断从服务器向客户端发送数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请查看以下示例

如您所见,某种事件一直在发送给客户端。我想在 consumers.py 内使用 Django-Channels 来模仿。这是我所拥有的简化版本:

As you can see, some sort of event is constantly being sent to the client. I want to imitate this using Django-Channels, inside consumers.py. Here's a simplified version of what I have:

class ChatConsumer(AsyncConsumer):
    async def ws_connect(self, event):
        self.send = get_db_object()

        ....

        await self.send({
            "type": "websocket.accept"
        })

    # I need to CONSTANTLY receive & send data
    async def ws_receive(self, event):

        obj = ...# query DB and get the newest object

        json_obj = {
            'field_1': obj.field_1,
            'field_2': obj.field_2,
        }

        await self.send({
            "type": "websocket.send",
            "text": json.dumps(json_obj)
        })


    @database_sync_to_async
    def get_db_object(self, **kwargs):
        return Some_Model.objects.get(**kwargs)[0]

此处,我希望我的Django后端能够不断运行:

Here, I want my Django backend to constantly:


  1. 查询数据库

  1. Query DB

从数据库接收obj

将接收到的obj作为事件发送到前端websocket

Send the received obj to Front-End websocket as event

如何实现?重要的是我需要不断将数据发送到客户端。

How can I achieve this? The important thing is that I need to CONSTANTLY send data to client.

Internet上的大多数 Django-Channels 资源仅涵盖聊天应用程序,不一定会不断发送数据发送给客户。我找不到能完成此工作的任何工作代码。

Most of the Django-Channels resources on the internet covers only Chat Apps, which doesn't necessarily constantly send data to client. I couldn't find any working codes that does this job.

请不要再为Redis或渠道文档推荐...或者一些缺少良好文档的随机第三方库....易于推荐但难以实现。例如,我发现有人推荐 Snorky ,但是它确实缺少有关如何实现它的文档。

Please, no more recommendation for redis or channels documentation... or some random 3rd party libraries that lacks good documentation.... It's easy to recommend but hard to implement. For example, I found someone recommending Snorky, but it really lacks documentation on how to implement it.

但是,如果有一个专门负责这项工作的网站,即使它不使用Django-Channels,我也可能会看一下。

However, if there's an website that specifically does this job, I might take a look at it, even if it doesn't use Django-Channels.

谢谢!

推荐答案

我找到了一个解决方案。由于我注意到这篇文章的观看次数在相对较短的时间内就上升了很多,我相信很多人都在想同样的事情,所以我将其发布在这里。

I've found a solution. Since I noticed the view count for this post went up pretty high in a relatively short time, I believe that lots of people are wondering the same thing, so I will post it here.

consumers.py

import asyncio
from channels.consumer import AsyncConsumer

class ChatConsumer(AsyncConsumer):

    async def websocket_connect(self, event):
        print("connected", event)
        await self.send({
            "type": "websocket.accept"
        })

        while True:
            await asyncio.sleep(2)

            obj = # do_something (Ex: constantly query DB...)

            await self.send({
                'type': 'websocket.send',
                'text': # obj,
            })

    async def websocket_receive(self, event):
        print("receive", event)

    async def websocket_disconnect(self, event):
        print("disconnected", event)

jQuery

<script>

var loc = window.location;
var wsStart = 'ws://';
if (loc.protocol == 'https:') {
    wsStart = 'wss://'
}
var endpoint = wsStart + loc.host + loc.pathname;

var socket = new WebSocket(endpoint);

socket.onmessage = function(e){
    console.log("message", e);
};
socket.onopen = function(e){
    console.log("open", e);
};
socket.onerror = function(e){
    console.log("error", e)
};
socket.onclose = function(e){
    console.log("close", e)
};
</script>

所有您需要做的就是修改 obj 并发送。您可以根据需要扩展此功能。因此,现在我有兴趣在PostgreSQL中获取最新插入的行,并将该行插入到我的websocket中。我可以按 await asyncio.sleep(2)指定的方式每2秒查询一次数据库,并将其注入到前端套接字中。

All you need to do is just modify obj and send it. You can extend this function as much as you want. So, right now I'm interested in getting the latest inserted row in my PostgreSQL, and injecting that row into my websocket. I can query my DB every 2 seconds as it was specified by await asyncio.sleep(2), and inject it into the Front-End socket.

希望有帮助。

这篇关于Django Channels-不断从服务器向客户端发送数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆