我正在尝试实现一个具有多个应用程序的 Django 项目,多个消费者的每个路径具有不同的 WebSocket 路由模式。
下面是我的工作代码,该代码可以工作,但显然不正确,我尝试了不同的方法,如 Django Chennels 文档 Django Channels - Routing 所示,但从未使其工作,
#asgi.py
from api.middleware import TokenAuthMiddleWare
from api.routing import websocket_urlpatterns
from live_tracker.routing import live_websocket_urlpatterns
application = ProtocolTypeRouter(
{
'http': get_asgi_application(),
'websocket': TokenAuthMiddleWare(AuthMiddlewareStack(URLRouter(websocket_urlpatterns))),
}
)
application = ProtocolTypeRouter(
{
'http': get_asgi_application(),
'websocket': AuthMiddlewareStack(URLRouter(live_websocket_urlpatterns)),
}
)
从我拥有的两个应用程序中,在第一个应用程序中,我已经做到了,因此需要令牌来访问
websocket_urlpatterns
,而在第二个应用程序中,我只需要默认的 django 身份验证:live_websocket_urlpatterns
。
我浏览了StackOverflows这个问题如何使用Django Channels使用多个websocket连接?这个问题只处理
AuthMiddlewareStack
,我有2个,一个自定义的TokenAuthMiddleWare
和django的默认AuthMiddlewareStack
有没有办法可以将 2 个应用程序合并为 1 个
applications
?
我们可以做到这一点,但我们不能在一个 Django 实例中使用两个
asgi
应用程序。为此,您需要使用 Docker 或 Kubernetes 之类的东西运行另一个整个容器
因此,您必须确保您的
urls.py
(对于 http 连接)或 routing.py
(对于 websocket 连接)都没有使用相同的路径。
例如,您有
api.routing
和 live_tracker.routing
,它们需要各自有自己独特的路径,例如“wss/connect_api”和“wss/connect_live_tracker”。
现在您需要将两个
urls.py
中的所有 http 路径放入一个文件 urls.py
中,由一个 asgi
应用程序使用。
您可以对两个 routing.py
文件中的 websocket 路径执行相同的操作,将它们合并到一个文件中。如果您想保留 api.routing
和 live_tracker.routing
那么您可以尝试获取 urlpattern 并将它们附加在一起,然后再设置 application
。
现在在您的
asgi.py
中,确保您仅创建 application
一次。在您的 settings.py
中,确保您的 ALLOWED HOSTS
中拥有您想要使用的两个网站的两个域。
我们的 Django 应用程序只知道通过 url 之后的路径引导流量。例如,如果您在domain1上有一个名为url1的url路径,您仍然可以从domain2访问它。
同一页
domain1.com/url1
domain2.com/url1
现在,这对您来说可能不是一个大问题,这就是我们在两个域上删除相同 url 路径的原因。如果我们不向用户提供前往那里的链接,那么这应该不是什么大问题......仍然如此。太不专业了。
针对敏感页面(例如需要登录用户的页面)解决此问题的一种方法是检查 cookie 以查看他们之前是否已登录,否则执行重定向。
这里有一个可能有点乏味的笼统 - 当请求实际达到
request.gethost()
时使用 views.py
。如果您的用户发现自己位于错误的域中,点击了错误的 url,请继续将他们重定向到正确的 url/域的主页或其他页面。