我们有一个使用Channels软件包的应用程序,在localhost上运行正常。一旦达到暂存状态,并在Django前面(使用SSL)放置了一个nginx
框,我们就可以连接到套接字,但是客户端没有收到任何消息。
Nginx conf:
worker_processes auto;
error_log /dev/stdout info;
user nobody nogroup;
pid /tmp/nginx.pid;
events {
worker_connections 1024;
accept_mutex off;
}
http {
include mime.types;
default_type application/octet-stream;
access_log /dev/stdout;
sendfile on;
keepalive_timeout 65;
gzip on;
gzip_disable "MSIE [1-6].(?!.*SV1)";
gzip_vary on;
upstream ws_server {
server unix:/tmp/daphne.sock fail_timeout=0;
}
server {
# redirect all http requests to https
listen 80;
listen [::]:80 ipv6only=on;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
client_max_body_size 4G;
server_name changemyip.com;
keepalive_timeout 5;
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;";
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets on;
ssl_dhparam /etc/nginx/ssl/dhparam.pem;
location /ws/ {
try_files $uri @proxy_to_ws;
}
location @proxy_to_ws {
proxy_pass http://ws_server;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Websocket specific
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
proxy_connect_timeout 86400;
proxy_read_timeout 86400;
proxy_send_timeout 86400;
}
...
ssl_protocols TLSv1.1 TLSv1.2;
...
ssl_prefer_server_ciphers on;
ssl_stapling on;
ssl_stapling_verify on;
}
}
Django使用gunicorn来运行,对于websocket,我启动了daphne服务器。我可以在daphne日志中看到我的客户端正在连接,但是仍然没有收到从daphne到客户端的消息。
达芙妮(Daphne)正在创建一个unix套接字,nginx会使用它来进行通信:
daphne main.asgi:channel_layer -u /tmp/daphne.sock
最佳答案
我有同样的问题。我无法通过unix套接字进行连接,但是我发现了一种非常简单的方法来使用系统端口来实现请求管理。我使用了以下教程(并利用了我对Gunicorn的经验),并设法对Nginx配置文件进行了一些修改,建议您将这些教程 checkout :
我的Nginx文件
# Enable upgrading of connection (and websocket proxying) depending on the
# presence of the upgrade field in the client request header
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
# Create an upstream alias to where we've set daphne to bind to
upstream django_app_server {
server 127.0.0.1:8000;
}
server {
listen 80;
server_name YOURDOMAIN.COM;
client_max_body_size 4G;
access_log /webapps/General/logs/nginx-access.log;
error_log /webapps/General/logs/nginx-error.log;
location /static/ {
alias /webapps/General/DjangoProject/static/;
}
location /media/ {
alias /webapps/General/DjangoProject/media/;
}
location / {
if (!-f $request_filename) {
proxy_pass http://django_app_server;
break;
}
# Require http version 1.1 to allow for upgrade requests
proxy_http_version 1.1;
# We want proxy_buffering off for proxying to websockets.
proxy_buffering off;
# http://en.wikipedia.org/wiki/X-Forwarded-For
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# enable this if you use HTTPS:
# proxy_set_header X-Forwarded-Proto https;
# pass the Host: header from the client for the sake of redirects
proxy_set_header Host $http_host;
# We've set the Host header, so we don't need Nginx to muddle
# about with redirects
proxy_redirect off;
# Depending on the request value, set the Upgrade and
# connection headers
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
# Error pages
error_page 500 502 503 504 /500.html;
location = /500.html {
root /webapps/General/DjangoProject/templates/;
}
}
我项目中的websocket运行得非常好(组和 channel ),并且所有请求都由Daphne处理,但是如果您确实需要使用套接字,那么此配置实际上可以为您提供帮助。
要考虑的要点
DEBUG==False
时daphne的worker是否可以提供静态文件和媒体文件,但是使用Nginx配置显然可以更好地为它们单独提供服务。 我知道这对您现在可能已经不重要了(我的意思是已经快一个月了),但是也许有人会对此答案有所帮助。
未知且相当奇怪的安全性问题
TL; DR :不要使用此配置在同一服务器上绘制两个Django-Daphne应用程序,否则您会遇到麻烦。
通过使用此配置,我能够将凤凰城应用程序与Django应用程序一起部署而没有任何类型的问题,但是当使用这种类型的配置部署2个或更多Django应用程序时,我遇到了问题。出于某种原因,达芙妮知道必须不断读取哪些端 Eloquent 能接收请求,但它只会读取所有这些端口,并根据需要将其提供给任何人。例如,如果我在同一服务器上运行
DJANGO_APP_1
和DJANGO_APP_2
(具有不同的Nginx配置和明显不同的系统端口),则有时DJANGO_APP_2
的Daphne Workers会窃取用于DJANGO_APP_1
的请求,反之亦然。我无法查明问题的根源,但我认为这与达芙妮的 worker 在某种程度上与他们所涉及的项目无关。 (只是一个理论,我没有时间检查他们的代码)。