Django Channels:如何将传入消息传递到 Django 外部 运行 的外部脚本?
Django Channels: How to pass incoming messages to external script which is running outside of django?
我已经用 Django 和 Channels 启动了一个私人项目来构建一个基于网络的 UI 来控制 raspberry pi 上的音乐播放器守护进程 (mpd)。我知道还有其他像 Volumio 或 moode audio 等开箱即用的项目也在做同样的事情,但我的目的是学习新东西!
到目前为止,我已经成功地在 pi 上设置了一个 nginx 服务器,它可以与我的移动设备 phone 或 pc 等设备进行通信。在后台,nginx 与 uWSGI 服务器通信以向 Django 发出 http 请求,并与作为 asgi 的 daphne 服务器通信以实现与 Django Channels 的 ws 连接。还安装了一个 redis 服务器作为后端,因为通道层需要它。因此,根据客户端请求,一个简单的 html 页面作为 UI 被提供,并且到目前为止已经建立了一个 websocket 连接。
与此同时,我有一个单独的脚本作为 mpd 处理程序,它被包裹在一个 while 循环中以使其保持活动状态,并且使用 python 模块 python- mpd2.
mpd 处理程序应通过 websocket 从 clients/consumers 获取其命令,如播放、停止等,并对此做出反应。同时,它应该在播放歌曲时发送歌曲的时间线,比方说每隔一秒通过 websocket。我可以设法从外部向所有使用 async_to_sync(channel_layer.group_send)
连接的 clients/consumers 频繁发送数据,但我找不到解决方案如何将来自客户端的 data/commands 通过 websocket 传递到我单独的 运行 mpd 处理程序脚本。
我在 Django Channels 的文档中读到,不建议在消费者中使用 while 循环,因为这会阻止所有通信——没错,我已经尝试过了。然后我尝试在直接连接到消费者的 mpd 处理程序中使用命令 async_to_sync(channel_layer.receive)('channel_name')
接收消息。但是这个命令阻止了我的 mpd 处理程序,因为它异步工作,尽管我使用 async_to_sync
.
那么,我的问题是:
是否可以使用通道自己的方法将消息传递到 Django 通道之外的其他脚本?您对如何使用其他方法或解决方法解决这个问题有什么建议吗?我正在寻找可靠的解决方案。
我思考过这个问题,有一些想法,但我不知道这是否会导致任何解决方案:
- 轮询:
客户端通过 websocket 频繁发送消息和请求来控制 mpd 并更新 UI。在这种情况下,不需要处理程序。 (我不知道这种方法是否会在 websocket 上产生大量流量并使其变慢。同样,必须经常建立与 mpd 的连接并再次关闭。不知道这是否有效。)
- 数据库:
生成消费者和 mpd 处理程序可以访问的数据库。消费者将传入的消息写入数据库,然后 mpd 处理程序将它们读出并完成工作。 (这里不知道consumer和mpd handler同时访问db会不会出问题。)
- 将队列与多处理模块一起使用:
消费者通过队列将消息传递给 mpd 处理程序。 (不知道可不可以)
- 在redis中抓取消息:
Mpd 处理程序经常在 Redis 上侦听以捕获消息。我读到,当层以通用方式使用时,组和通道名称仅在 redis 上列出。当消费者作为工人启动时,消息通过 redis 传递。 (这意味着我的所有消费者都必须从后台工作人员开始,但如何?)
希望您能解决我的问题。从我的想法和解决这个问题所涉及的问号中,您可能会意识到我不是IT专家。正如我在开头所写,我有另一个工程背景和一个新手,但非常有兴趣学习新东西!所以当我不能立即理解所有内容时,请耐心等待我。
希望能尽快看到您的回答,在此先感谢您。
此致。
虽然没有人回答我的问题,但我尝试了一些可能的选择。
我将 mpd 的绑定从固定 IP 更改为套接字连接,并创建了一个 mpd_Handler class,其中包含一些 functions/methods,例如连接到 mpd、断开连接、播放、暂停等。
这个 class 是在 Django consumers.py 和 views.py 中导入的。每当 Web 客户端连接到 Django 或有新命令(如播放、跳过等)时,mpd_Handler 将执行命令并响应 mpd 的实际状态,如当前歌曲元数据。
第二个 mpd 处理程序在 Django 之外 运行 作为单独的脚本经常监视 mpd 状态以检测任何更改。如果 mpd 发生变化(例如,网络广播流的歌曲或歌曲的持续时间发生变化),此处理程序会使用命令 async_to_sync(channel_layer.group_send)
通知所有连接到 Django 消费者组的客户端,以便客户端可以更新他们的 UI.
目前有效,我希望这是一个很好的解决方案,可以帮助遇到同样问题的其他人。仍然欢迎其他建议!
此致。
我已经用 Django 和 Channels 启动了一个私人项目来构建一个基于网络的 UI 来控制 raspberry pi 上的音乐播放器守护进程 (mpd)。我知道还有其他像 Volumio 或 moode audio 等开箱即用的项目也在做同样的事情,但我的目的是学习新东西!
到目前为止,我已经成功地在 pi 上设置了一个 nginx 服务器,它可以与我的移动设备 phone 或 pc 等设备进行通信。在后台,nginx 与 uWSGI 服务器通信以向 Django 发出 http 请求,并与作为 asgi 的 daphne 服务器通信以实现与 Django Channels 的 ws 连接。还安装了一个 redis 服务器作为后端,因为通道层需要它。因此,根据客户端请求,一个简单的 html 页面作为 UI 被提供,并且到目前为止已经建立了一个 websocket 连接。
与此同时,我有一个单独的脚本作为 mpd 处理程序,它被包裹在一个 while 循环中以使其保持活动状态,并且使用 python 模块 python- mpd2.
mpd 处理程序应通过 websocket 从 clients/consumers 获取其命令,如播放、停止等,并对此做出反应。同时,它应该在播放歌曲时发送歌曲的时间线,比方说每隔一秒通过 websocket。我可以设法从外部向所有使用 async_to_sync(channel_layer.group_send)
连接的 clients/consumers 频繁发送数据,但我找不到解决方案如何将来自客户端的 data/commands 通过 websocket 传递到我单独的 运行 mpd 处理程序脚本。
我在 Django Channels 的文档中读到,不建议在消费者中使用 while 循环,因为这会阻止所有通信——没错,我已经尝试过了。然后我尝试在直接连接到消费者的 mpd 处理程序中使用命令 async_to_sync(channel_layer.receive)('channel_name')
接收消息。但是这个命令阻止了我的 mpd 处理程序,因为它异步工作,尽管我使用 async_to_sync
.
那么,我的问题是:
是否可以使用通道自己的方法将消息传递到 Django 通道之外的其他脚本?您对如何使用其他方法或解决方法解决这个问题有什么建议吗?我正在寻找可靠的解决方案。
我思考过这个问题,有一些想法,但我不知道这是否会导致任何解决方案:
- 轮询: 客户端通过 websocket 频繁发送消息和请求来控制 mpd 并更新 UI。在这种情况下,不需要处理程序。 (我不知道这种方法是否会在 websocket 上产生大量流量并使其变慢。同样,必须经常建立与 mpd 的连接并再次关闭。不知道这是否有效。)
- 数据库: 生成消费者和 mpd 处理程序可以访问的数据库。消费者将传入的消息写入数据库,然后 mpd 处理程序将它们读出并完成工作。 (这里不知道consumer和mpd handler同时访问db会不会出问题。)
- 将队列与多处理模块一起使用: 消费者通过队列将消息传递给 mpd 处理程序。 (不知道可不可以)
- 在redis中抓取消息: Mpd 处理程序经常在 Redis 上侦听以捕获消息。我读到,当层以通用方式使用时,组和通道名称仅在 redis 上列出。当消费者作为工人启动时,消息通过 redis 传递。 (这意味着我的所有消费者都必须从后台工作人员开始,但如何?)
希望您能解决我的问题。从我的想法和解决这个问题所涉及的问号中,您可能会意识到我不是IT专家。正如我在开头所写,我有另一个工程背景和一个新手,但非常有兴趣学习新东西!所以当我不能立即理解所有内容时,请耐心等待我。
希望能尽快看到您的回答,在此先感谢您。
此致。
虽然没有人回答我的问题,但我尝试了一些可能的选择。
我将 mpd 的绑定从固定 IP 更改为套接字连接,并创建了一个 mpd_Handler class,其中包含一些 functions/methods,例如连接到 mpd、断开连接、播放、暂停等。
这个 class 是在 Django consumers.py 和 views.py 中导入的。每当 Web 客户端连接到 Django 或有新命令(如播放、跳过等)时,mpd_Handler 将执行命令并响应 mpd 的实际状态,如当前歌曲元数据。
第二个 mpd 处理程序在 Django 之外 运行 作为单独的脚本经常监视 mpd 状态以检测任何更改。如果 mpd 发生变化(例如,网络广播流的歌曲或歌曲的持续时间发生变化),此处理程序会使用命令 async_to_sync(channel_layer.group_send)
通知所有连接到 Django 消费者组的客户端,以便客户端可以更新他们的 UI.
目前有效,我希望这是一个很好的解决方案,可以帮助遇到同样问题的其他人。仍然欢迎其他建议!
此致。