我正在开发 Django Channels-2项目 ,其中 频道图层 用于卸载信息从浏览器到分析它的消费者,并通过 groups 机制将结果发送回浏览器。
数据来自 推送器 ,通过 pusher-client ,因此对于许多客户来说都是一样的浏览器。我首先考虑的是建立以下基础设施:
布局1:
( browser1: Pusher-client,websocket; ... browserN: Pusher-client,websocket)
< ---->
WebsocketConsumer (组成员;发送到频道,从组收到)
< ---->
BackgroundWorker (收听频道;发送至群组)
这种布局工作正常,它减轻了使用推送器连接给我的服务器带来负担的需要,这种连接留给了各个浏览器。但这也意味着我将同一事件的多个副本传播给我的工作人员。我知道有这个问题的解决方案,但他们似乎有点尴尬。此外,这意味着浏览器中存在大量JavaScript。更重要的是,因为每个浏览器选项卡只允许一个websocket连接,我需要通过同一个套接字来传输所有内容。因此我现在使用以下设置:
布局2:
( browser1: websocket; ... browserN: websocket)
< ---->
WebsocketConsumer (组成员;发送到频道,从组收到)
< ---->
BackgroundWorker ( 推送客户端 ;侦听频道;发送至群组强>)
在此布局中,浏览器通知消费者它想要数据的结果,如果后台工作者尚未启动,则它会生成并启动推送客户端,并且在收到的每个事件上分析数据并将结果发送到组,因此回到浏览器。这一切都非常好,很好。
问题:
现在,当我跑
./manage.py runworker *channel-name*
工作者消费者在实际需要之前不会启动。当第一条消息到达它监听的通道时,它会被启动并进入推送器 - 客户端的事件循环。看来,后续调用不会产生额外的工作,如果推动器已经启动,我会有一个标志,所以我只有一个连接到推动器的活动。
Q1:我可以指望后台消费者在启动后保持活跃状态,或者是否存在超时或者如果在通道中没有要读取新消息的话?
Q2:我的操作是否有更好/更多可靠的布局?
我还有一个外部websocket服务器版本,其中pusher处于活动状态且结果可用,但我没有看到如何优雅地将它集成到django渠道项目中,尽管它工作得非常好。这是一个更好的方法并使用unix-socket吗?
非常感谢您的投入!
[编辑1]
我在 频道-1.x 系列文档中找到了常见问题解答部分中的一个条目,即可以通过外部通过Django频道应用进行通信直接 频道图层 。所以这就是我现在正在测试的方法,它的工作非常精彩。所以我目前这样做。由于 Q1 和 Q2 仍然有效且我感兴趣,我会保持这个问题。
在编辑的其余部分显示了目前为感兴趣的内容如何完成的快速概述:
External.py
from <proj-name>.asgi import channel_layer
from asgiref.sync import async_to_sync
import pysher
...
# External program logic #
...
# Channel layer communication -> send_group #
async_to_sync(channel_layer.group_send)(
<group>,
{
'type': "<type>",
'data': <dict>,
}
)
Django频道项目的asgi.py文件中的
import os
import django
from channels.routing import get_default_application
from channels.layers import get_channel_layer
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "<proj-name>.settings")
django.setup()
application = get_default_application()
# || the important part for us || #
# vv vv #
channel_layer = get_channel_layer()
我正在运行Django Channels 2.x系列,它与1.x系列略有不同。这种设置完全消除了对后台工作者的需求,将pusher和django分离,使得事情变得更容易。