Django 频道 + Elastic Beanstalk

Posted

技术标签:

【中文标题】Django 频道 + Elastic Beanstalk【英文标题】:Django Channels + Elastic Beanstalk 【发布时间】:2017-07-25 00:12:03 【问题描述】:

我已经设置了一个应用程序负载平衡器,它将 /ws/ 请求重定向到端口 5000,在那里我让 Daphne 和 4 个工作人员(通过 Supervisord 重新加载)一起运行。但是,在 Chrome 控制台中我收到错误

WebSocket connection to 'wss://api.example.com/ws/' failed: WebSocket is closed before the connection is established.

当尝试通过简单的 javascript 代码连接到我的 WebSocket 时(请参阅 Multichat 以了解非常接近的内容)。有什么想法吗?

路由.py

websocket_routing = [
# Called when WebSockets connect
route("websocket.connect", ws_connect),

# Called when WebSockets get sent a data frame
route("websocket.receive", ws_receive),

# Called when WebSockets disconnect
route("websocket.disconnect", ws_disconnect),
]

Settings.py

# Channel settings
CHANNEL_LAYERS = 
"default": 
    "BACKEND": "asgi_redis.RedisChannelLayer",
    "CONFIG": 
        "hosts": ["redis://:xxxxx@xxxx-redis.xxxxx.1234.usxx.cache.amazonaws.com:6379/0"],
    ,
    "ROUTING": "Project.routing.channel_routing",
,


Supervisord.conf

[program:Daphne]
environment=PATH="/opt/python/run/venv/bin"
environment=LD_LIBRARY_PATH="/usr/local/lib"
command=/opt/python/run/venv/bin/daphne -b 0.0.0.0 -p 5000 Project.asgi:channel_layer
directory=/opt/python/current/app
autostart=true
autorestart=true
redirect_stderr=true
stdout_logfile=/tmp/daphne.out.log
[program:Worker]
environment=PATH="/opt/python/run/venv/bin"
environment=LD_LIBRARY_PATH="/usr/local/lib"
command=/opt/python/run/venv/bin/python manage.py runworker -v2
directory=/opt/python/current/app
process_name=%(program_name)s_%(process_num)02d
numprocs=4
autostart=true
autorestart=true
redirect_stderr=true
stdout_logfile=/tmp/workers.out.log

daphne.out.log

2017-03-05 00:58:24,168 INFO     Starting server at tcp:port=5000:interface=0.0.0.0, channel layer Project.asgi:channel_layer.
2017-03-05 00:58:24,179 INFO     Using busy-loop synchronous mode on channel layer
2017-03-05 00:58:24,182 INFO     Listening on endpoint tcp:port=5000:interface=0.0.0.0

workers.out.log

2017-03-05 00:58:25,017 - INFO - runworker - Using single-threaded worker.
2017-03-05 00:58:25,019 - INFO - runworker - Using single-threaded worker.
2017-03-05 00:58:25,010 - INFO - runworker - Using single-threaded worker.
2017-03-05 00:58:25,020 - INFO - runworker - Running worker against channel layer default (asgi_redis.core.RedisChannelLayer)
2017-03-05 00:58:25,020 - INFO - worker - Listening on channels chat.receive, http.request, websocket.connect, websocket.disconnect, websocket.receive
2017-03-05 00:58:25,021 - INFO - runworker - Running worker against channel layer default (asgi_redis.core.RedisChannelLayer)
2017-03-05 00:58:25,021 - INFO - worker - Listening on channels chat.receive, http.request, websocket.connect, websocket.disconnect, websocket.receive
2017-03-05 00:58:25,021 - INFO - runworker - Running worker against channel layer default (asgi_redis.core.RedisChannelLayer)
2017-03-05 00:58:25,022 - INFO - worker - Listening on channels chat.receive, http.request, websocket.connect, websocket.disconnect, websocket.receive
2017-03-05 00:58:25,029 - INFO - runworker - Using single-threaded worker.
2017-03-05 00:58:25,029 - INFO - runworker - Running worker against channel layer default (asgi_redis.core.RedisChannelLayer)
2017-03-05 00:58:25,030 - INFO - worker - Listening on channels chat.receive, http.request, websocket.connect, websocket.disconnect, websocket.receive

失败前运行的 JavaScript 代码

// Correctly decide between ws:// and wss://
var ws_scheme = window.location.protocol == "https:" ? "wss" : "ws";
var ws_path = ws_scheme + '://' + window.location.host + "/ws/";
console.log("Connecting to " + ws_path);
var socket = new ReconnectingWebSocket(ws_path);

显然,daphne/worker 日志中没有相关输出,这意味着连接可能一开始就没有正确路由。

【问题讨论】:

【参考方案1】:

一切都已正确设置——这是权限问题。密切关注所有相关的 AWS 安全组(负载均衡器和属于目标组的实例)。

【讨论】:

嗨@Faris。您是如何禁用正常的 wsgi 主管脚本的。您是否还必须修改 apache conf 文件以启用 ws 支持。谢谢 wsgi 仍然在端口 80 上运行,daphne 在端口 5000 上运行。另外我不认为 wsgi 是由弹性豆茎上的主管运行的,如果我错了,有人纠正我,但我看到的唯一进程是httpd

以上是关于Django 频道 + Elastic Beanstalk的主要内容,如果未能解决你的问题,请参考以下文章

Django Channels 2.4 和 Websockets 在 Elastic Beanstalk 和 ElastiCache 上给出 502 错误

Elastic Beanstalk - 实例上的命令失败。发生意外错误 [错误代码:0000000001]

Django - Celery Worker - 频道

Django 频道:消息在一个频道中重复

使用 django 频道时如何使用频道而不是组?

Django 频道“组订阅中 N 个频道中的 ERROR Y 超出容量”