Django 现在在 Heroku 中使用 ASGI + WSGI 的频道
Posted
技术标签:
【中文标题】Django 现在在 Heroku 中使用 ASGI + WSGI 的频道【英文标题】:Django now working channels with ASGI + WSGI in Heroku 【发布时间】:2019-10-16 13:17:35 【问题描述】:我正在尝试使用 Channels (V.2) 设置 Django + Heroku 应用程序。 我尝试按照所有教程进行操作,但其中大多数都没有更新。 应用程序必须对 HTTP 请求使用 WSGI,对 websockets 请求使用 ASGI。 到目前为止,我发现它几乎可以正常工作,最后缺少的部分是 websockets 端点对 web 应用程序可见。 此时每当我尝试创建一个新的 websocket 时:
WebSocket 握手期间出错:意外响应代码:404
设置如下:
ASGI_APPLICATION = 'app_xxx.routing.application'
ASGI_THREADS = 5
WSGI_APPLICATION = 'app_xxx.wsgi.application'
CHANNEL_LAYERS =
"default":
"BACKEND": "channels_redis.core.RedisChannelLayer",
"CONFIG":
'hosts': [os.environ.get('REDIS_URL')],
,
,
这是 Procfile:
web: gunicorn app_xxx.wsgi --log-file -
web2: daphne app_xxx.asgi:channel_layer --port $PORT --bind 0.0.0.0 -v2
worker: python manage.py runworker channel_layer -v2
这是asgi:
import os
from channels.layers import get_channel_layer
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "app_xxx.settings")
channel_layer = get_channel_layer()
这里是路由:
from channels.routing import ProtocolTypeRouter, URLRouter, ChannelNameRouter
from django.urls import path
from apps.booking.consumers import BookingConsumer
application = ProtocolTypeRouter(
"websocket": URLRouter([
path('ws/booking_review/<room_name>', BookingConsumer),
]),
)
【问题讨论】:
【参考方案1】:您应该运行 ASGI 应用程序,而不是通道层。您的ASGI_APPLICATION
设置应该指向routing.py
,或者您可以将其内容移动到asgi.py
并指向它。根据您当前的配置,您的 Procfile 应如下所示:
web: gunicorn app_xxx.wsgi --log-file -
web2: daphne app_xxx.routing:application --port $PORT --bind 0.0.0.0 -v2
worker: python manage.py runworker channel_layer -v2
查看文档deployment page 了解更多详情
【讨论】:
感谢您的回复。可悲的是,这也不起作用,我可以看到 daphne 应用程序已启动,但 websockets 请求从未到达 web2 dyno @Du_ 实际上从我读到的内容来看,Heroku 只允许每个应用程序打开一个端口,这就是为什么你只能拥有一个网络测功机。所以基本上 daphne 服务不能在那个端口上运行,因为它已经被 gunicorn 服务占用了。所以你唯一的选择可能是使用 daphne 来处理 HTTP 和 websocket 请求 这是有道理的。然而,仅使用带有 Postgres + Channels (Redis) 的 daphne 有一个市长骗局。连接永远不会关闭,使应用达到 20 个连接的最大限制 @Du_ 这部分文档channels.readthedocs.io/en/latest/topics/authentication.html 讨论了您应该手动关闭连接的情况。如果你将它与database_sync_to_async
正确结合,它会在任务结束时自动关闭数据库连接,它应该可以正常工作而没有太多问题
我有同样的问题,但我收到此错误Error during WebSocket handshake: Unexpected response code: 200
。您的意思是 Heroku 根本不允许您运行 2 个端口,即使您可以拥有多个测功机?以上是关于Django 现在在 Heroku 中使用 ASGI + WSGI 的频道的主要内容,如果未能解决你的问题,请参考以下文章
在 Heroku 上的 Django 应用程序中为 CORS 指定 URL
如何使用 Heroku 和 Django 实现简单的 cron 作业