我需要启动一个工人吗?

Do I need to start a worker?

我在某处读到,如果我在代码中的某处使用了 channel_layer.send(....),我只需要启动一个 worker。

这是正确的吗?我以为工作人员是处理所有 WebSocket 请求的人。

您的问题背后有许多有趣的概念需要澄清。 让我们先从 WebSocket 的使用开始。

WebSocket

WebSocket 很可能是您使用 Django Channels 的主要兴趣,因为 Django 单独管理 HTTP。

为此,您不需要通道层,也不需要 运行 worker。

在开发中,这是您通常看到的启动标准 Django 项目的内容:

$ python manage.py runserver

Performing system checks...
...
Django version 2.1.5, using settings 'djlistener.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

但是,将 channels 添加到 INSTALLED_APPS 并按照 Django Channels 文档的建议定义 ASGI_APPLICATION 设置,您会注意到输出略有不同:

$ python manage.py runserver

Performing system checks...
...
Django version 2.1.5, using settings 'djlistener.settings'
Starting ASGI/Channels version 2.1.6 development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

那是因为 Channels 的开发服务器已经接管了 Django 开发服务器,您可以立即开始使用 HTTP 和 WebSocket 通信。

生产中:

  • 您可以选择将 Daphne 用于 HTTP 和 WebSockets 请求,因为 Daphne 将在 HTTP 和 WebSocket 之间自动协商。

  • 或者,您可以拆分 HTTP 和 WebSocket 流量:运行 通过 WSGI 服务器的标准 HTTP 请求,并且仅将 Daphne(或 uvicorn)用于 WSGI 不能做的事情,如 WebSockets、HTTP长轮询或其他物联网协议。

参考文献:

通道层

从 2.0 版开始,通道层是通道的一个完全可选的部分。

它们提供了一种抽象,允许您出于多种目的在应用程序的不同实例之间进行对话。

怎么样?当您发送一条消息时,另一端收听该组或频道的消费者会收到该消息。

我使用通道层的主要动机是组概念,它让我可以向所有注册(在连接时)特定组的 WebSocket 客户端广播消息。为此,我不需要工作人员:我使用 channel_layer.group_send() 将我的消息发送到组,然后通道层将其传递给消费者,后者又将其发送给 WebSocket 客户端。

工人和后台任务

通道层的一个非常具体的用途是将一些工作委托给一组监听固定通道名称的工作服务器,作为一个简单的任务队列。

此处 (且仅此处)runworker 命令的用武之地。

大多数情况下,您会为此使用其他著名的解决方案,例如 Celery 或 Django-rq;但在某些情况下,对于简单的后台任务队列来说,这可能是一种廉价且延迟非常低的替代方案。

参考文献:

Worker and Background Tasks