【发布时间】:2021-07-24 14:09:56
【问题描述】:
我已经使用 Django 和 Channels 开始了一个私人项目,以构建一个基于 Web 的 UI 来控制树莓派上的音乐播放器守护程序 (mpd)。我知道还有其他开箱即用的项目,例如 Volumio 或 moode audio 等,但我的目的是学习新东西!
到目前为止,我已经设法在 pi 上设置了一个 nginx 服务器,用于与我的手机或 PC 等设备进行通信。在后台,nginx 与一个 uWSGI 服务器进行通信,用于对 Django 的 http 请求,并与一个 daphne 服务器作为 asgi 进行 ws 连接到 Django 频道。还安装了一个 redis 服务器作为后端,因为 Channels 层需要这个。因此,根据客户端请求,提供一个简单的 html 页面作为 UI,并且到目前为止建立了 websocket 连接。
并行地,我有一个单独的脚本作为 mpd 处理程序,它被包裹在一个 while 循环中以使其保持活动状态,并使用 python 模块 python-mpd2 与 mpd 一起完成所有工作。
mpd 处理程序应通过 websocket 从客户端/消费者那里获取其命令,例如播放、停止等,并对此做出反应。同时,它会在歌曲播放时发送歌曲的时间线,比如说每隔一秒,也可以通过 websocket 发送。我可以设法从外部使用async_to_sync(channel_layer.group_send) 频繁地向所有连接的客户端/消费者发送数据,但我找不到如何将来自客户端的数据/命令通过 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 处理程序将它们读出并完成工作。 (这里不知道consumers和mpd handler同时访问db会不会出现问题。)
- 将队列与多处理模块一起使用: 消费者通过队列将消息传递给 mpd 处理程序。 (不知道这是否可行。)
- 在 redis 中获取消息: Mpd 处理程序经常在 redis 上侦听以赶上消息。我读到,当层以通用方式使用时,组和通道名称仅在 redis 上列出。当消费者作为工人启动时,消息通过 redis 传递。 (这意味着我的所有消费者都必须从后台工作人员开始,但如何?)
我希望你能解决我的问题。您可能从我的想法和解决这个问题所涉及的问号中意识到我不是 IT 专家。正如我在开头所写的那样,我有另一个工程背景和一个新手,但对学习新东西非常感兴趣!所以当我不能立即理解所有内容时,请耐心等待。
我希望尽快阅读您的答案,并提前感谢您。
最好的问候。
【问题讨论】:
标签: python django websocket redis django-channels