引入 Django Channels 时是不是需要更改我的正常 Django 代码?

Posted

技术标签:

【中文标题】引入 Django Channels 时是不是需要更改我的正常 Django 代码?【英文标题】:Do I need to change my normal Django code when introducing Django Channels?引入 Django Channels 时是否需要更改我的正常 Django 代码? 【发布时间】:2020-10-14 02:08:22 【问题描述】:

您好我是python世界的初学者,所以我仍然在尝试了解使用ASGI时的注意事项。我阅读了一些教程和文档,并在 youtube 上观看了一些视频。但是,我在某些方面不确定。

我有一个使用 Django + Django Rest Framework 的小型后端应用程序。

我的代码很琐碎,由框架中最常见的概念组成:视图、序列化器、模型、url等。另外,我使用的是关系数据库。

我的环境是这样的:

Python 3.8 Django 3 Django 休息框架 3.11

现在,我需要添加对 WebSockets 的支持,并且我做了 Django Channels 教程中描述的基本配置:

我安装了 Django Channels 2.4.0 (Daphene 2.5.0) 向 INSTALLED_APPS 添加了“频道” 我创建了一个带有空 ProtocolTypeRouter 的 routing.py 文件 我将 ASGI_APPLICATION 添加到我的 settings.py 中 我将 asgi.py 文件配置为使用通道 目前我还没有配置任何通道层 目前,我还没有创建任何 WebSocket 端点

在这些配置之后,运行服务器正在使用 ASGI 开发服务器,显然我的 REST 端点都在工作。

一些问题:

考虑到我所有的代码都是同步的,难道没有必要对其进行任何调整吗?

考虑到它是一个 ASGI 服务器,上面的这个配置已经完成了我的同步代码在 daphene 中安全执行所需的所有魔法?

我能否以可靠和稳定的方式仅使用 ASGI 来处理正常的 HTTP 和 WebSockets 请求?或者,是否建议使用 WSGI 提供 HTTP 流量,而只将 WebSockets 流量留给 daphene?

关于同步代码究竟应该注意哪些方面?

【问题讨论】:

Marlon,你是单独使用 django-channels,还是同时使用可选的 channel-layers 组件? 目前只有 django-channels,但很快我们会考虑用 Redis 引入通道层。 【参考方案1】:

这些是我根据以前使用 Django Channels 2 的经验得出的答案...

1) 考虑到我所有的代码都是同步的,是不是需要做一些调整?

您可以安全地保留现有的同步代码:无需调整;只需确保调用 django-channels API 的“同步版本”(即 SyncConsumer 而不是 AsyncConsumer)。

另一方面,Channel Layers 使用不同的方法,并且仅提供异步版本。 当从同步代码发出调用时,您需要使用 async_to_sync 包装器;例如:

from asgiref.sync import async_to_sync

async_to_sync(channel_layer.group_send)(
    group, 
        "type": 'data_received',
        "content": data,
    )

2) 考虑到它是一个 ASGI 服务器,上面的这个配置已经完成了我的同步代码在 daphene 中安全执行所需的所有魔法?

唯一缺少的细节是(在设置文件中):

ROOT_URLCONF = 'project.urls'

3) 我能否以可靠和稳定的方式仅使用 ASGI 来处理正常的 HTTP 和 WebSockets 请求?或者,是否建议使用 WSGI 服务 HTTP 流量,而只将 WebSockets 流量留给 daphene?

使用 Channels 2,您可以安全地选择对 HTTP 和 WebSockets 请求使用 Daphne,因为 Daphne 将在 HTTP 和 WebSockets 之间自动协商;这是我在项目中通常会做的事情。

拆分 HTTP 和 WebSocket 流量,因此:

通过 WSGI 服务器运行标准 HTTP 请求 仅将 Daphne(或 uvicorn)用于 WSGI 无法执行的操作,例如 WebSocket、HTTP 长轮询或其他 IoT 协议

是可能的,但完全是可选的。

【讨论】:

以上是关于引入 Django Channels 时是不是需要更改我的正常 Django 代码?的主要内容,如果未能解决你的问题,请参考以下文章

Django Channels 是不是使用 ws:// 协议前缀在 Django 视图或 Channels 应用程序之间进行路由?

Django Channels 2.4 ... WebSocket 消息是不是总是按顺序到达

代码发布项目——django实现websocket(使用channels)基于channels实现群聊功能gojs插件paramiko模块

使用 django-channels/websocket 更新实时位置的有效方法

Django Channels 中间件使用 ORM

Django 通道 websocket 连接和断开连接(Nginx + Daphne + Django + Channels)