部署Django Channels+Apache2+Daphne时WebSocket连接失败求助
Django Channels部署WebSocket连接失败排查
开发环境中使用Django Channels一切正常,但部署到本地服务器后出现问题。当前采用Apache2提供应用服务,将WebSocket请求转发至Daphne,页面可正常加载,但浏览器控制台提示WebSocket connection to 'wss://MYDOMAIN/ws/main/' failed:错误。以下是相关配置文件及排查建议:
Apache配置
<VirtualHost *:444> ServerName myDomain ServerAdmin admin DocumentRoot /var/www/thomasmichaelides/public_html ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined # Enable Websocket connections RewriteEngine on RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC,OR] RewriteCond %{HTTP:CONNECTION} ^Upgrade$ [NC] RewriteRule .* ws://127.0.0.1:8001%{REQUEST_URI} [P,QSA,L] Alias /static /home/atwebapps/arduinoDjango/static <Directory /home/atwebapps/arduinoDjango/static> Require all granted </Directory> <Directory /home/atwebapps/arduinoDjango/arduinoDjango> <Files wsgi.py> Require all granted </Files> </Directory> WSGIScriptAlias / /home/atwebapps/arduinoDjango/arduinoDjango/wsgi.py WSGIDaemonProcess arduinoApp python-path=/home/atwebapps/arduinoDjango python-home=/home/atwebapps/arduinoDjango/venv WSGIProcessGroup arduinoApp SSLCertificateFile /etc/letsencrypt/live/mydomain/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/mydomain/privkey.pem Include /etc/letsencrypt/options-ssl-apache.conf </VirtualHost>
daphne.service配置
[Unit] Description=WebSocket Daphne Service After=network.target [Service] Type=simple User=root WorkingDirectory=/home/atwebapps/arduinoDjango ExecStart=/home/atwebapps/arduinoDjango/venv/bin/python /home/atwebapps/arduinoDjango/venv/bin/daphne -b 0.0.0.0 -p 8001 arduinoDjango.asgi:application Restart=on-failure [Install] WantedBy=multi-user.target
asgi.py文件
""" ASGI config for arduinoDjango project. It exposes the ASGI callable as a module-level variable named ``application``. For more information on this file, see https://docs.djangoproject.com/en/3.2/howto/deployment/asgi/ """ import os from django.core.asgi import get_asgi_application os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'arduinoDjango.settings') application = get_asgi_application()
settings.py中Channels相关配置
INSTALLED_APPS = [ 'main.apps.MainConfig', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'rest_framework', 'channels', 'corsheaders', ] MIDDLEWARE = [ 'corsheaders.middleware.CorsMiddleware', 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] WSGI_APPLICATION = 'arduinoDjango.wsgi.application' ASGI_APPLICATION = 'arduinoDjango.routing.application' CHANNEL_LAYERS = { "default": { "BACKEND": "channels_redis.core.RedisChannelLayer", "CONFIG": { "hosts": [("localhost", 6379)], }, }, } use_websockets = True
排查建议
- 端口匹配检查:Apache的VirtualHost配置为
*:444,但wss协议默认端口是443。确认前端请求的WebSocket URL是否包含:444端口(如wss://MYDOMAIN:444/ws/main/),或修改Apache配置为*:443以匹配默认SSL端口。 - Apache模块启用检查:确保
mod_proxy、mod_proxy_wstunnel和mod_ssl模块已启用,执行以下命令并重启Apache:a2enmod proxy proxy_wstunnel ssl systemctl restart apache2 - ASGI配置修正:当前
asgi.py仅返回Django的HTTP ASGI应用,未处理WebSocket请求。需修改asgi.py,引入Channels的路由处理逻辑:
同时确认项目中存在import os from django.core.asgi import get_asgi_application from channels.routing import ProtocolTypeRouter, URLRouter from channels.auth import AuthMiddlewareStack # 替换为你实际的路由模块路径 from main.routing import websocket_urlpatterns os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'arduinoDjango.settings') application = ProtocolTypeRouter({ "http": get_asgi_application(), "websocket": AuthMiddlewareStack( URLRouter(websocket_urlpatterns) ), })routing.py文件,定义了WebSocket的URL路由规则。 - Daphne服务状态检查:查看Daphne是否正常启动,执行:
确认端口8001被监听:systemctl status daphne.service journalctl -u daphne.service -fnetstat -tulpn | grep 8001 - Redis服务检查:CHANNEL_LAYERS依赖Redis,确认Redis服务运行正常:
查看Daphne日志中是否有Redis连接失败的报错。systemctl status redis-server - SSL配置验证:确认Apache的SSL证书路径正确,文件权限正常,
mod_ssl模块已启用。 - 日志分析:查看Apache的错误日志(
${APACHE_LOG_DIR}/error.log)和访问日志,以及浏览器控制台的具体错误信息(如握手失败、超时等),定位更精确的问题原因。
内容的提问来源于stack exchange,提问作者Thomas Michaelides
相关产品推荐
相关产品推荐

