Apache配置Daphne实现Django WebSocket连接失败求助
解决Django+Daphne+Apache环境下WebSocket 404连接失败问题
核心问题分析
从错误日志Not Found: /ws/video_call/可以看出,WebSocket请求被Apache的WSGI模块处理了,没有转发到Daphne服务器。当前Apache配置存在两处关键错误:
- WebSocket代理配置放在了80端口的虚拟主机中,而请求通过HTTPS(wss协议)访问,80端口的重定向规则会导致代理规则失效。
- ProxyPass目标使用了
wss://kartikprajapati.com:8001/,但Daphne监听的是普通HTTP(ws)端口,转发时无需使用SSL。
分步解决方案
1. 修正Apache HTTPS虚拟主机配置
创建或修改HTTPS虚拟主机配置文件(通常位于/etc/apache2/sites-available/目录,示例文件名为kartikprajapati.com-le-ssl.conf):
<VirtualHost *:443> ServerName www.kartikprajapati.com ServerAdmin kartikprajapati26122004@gmail.com ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined # SSL证书配置(根据实际证书路径调整) SSLCertificateFile /etc/letsencrypt/live/www.kartikprajapati.com/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/www.kartikprajapati.com/privkey.pem Include /etc/letsencrypt/options-ssl-apache.conf # 静态/媒体文件映射 Alias /static /var/www/mywebsite/static <Directory /var/www/mywebsite/static> Require all granted </Directory> Alias /media /var/www/mywebsite/media <Directory /var/www/mywebsite/media> Require all granted </Directory> # WebSocket转发规则 RewriteEngine On # 匹配WebSocket升级请求,转发到Daphne RewriteCond %{HTTP:Upgrade} =websocket [NC] RewriteRule /ws/(.*) ws://localhost:8001/ws/$1 [P,L] # 普通HTTP请求由WSGI处理 WSGIDaemonProcess mywebsite python-home=/var/www/mywebsite/venv python-path=/var/www/mywebsite WSGIProcessGroup mywebsite WSGIScriptAlias / /var/www/mywebsite/mywebsite/wsgi.py <Directory /var/www/mywebsite/mywebsite> <Files wsgi.py> Require all granted </Files> </Directory> # 确保WebSocket路径不被WSGI拦截 <Location /ws/> ProxyPass ws://localhost:8001/ws/ ProxyPassReverse ws://localhost:8001/ws/ ProxyPreserveHost On </Location> </VirtualHost>
2. 简化80端口虚拟主机配置
保留80端口的重定向规则即可,删除原有的WebSocket代理配置:
<VirtualHost *:80> ServerName www.kartikprajapati.com ServerAdmin kartikprajapati26122004@gmail.com ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined RewriteEngine on RewriteCond %{SERVER_NAME} =www.kartikprajapati.com RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent] </VirtualHost>
3. 验证Apache模块是否启用
确保所需模块已启用并重启Apache:
a2enmod proxy proxy_http proxy_wstunnel rewrite systemctl restart apache2
4. 检查ASGI路由与Daphne配置
- 当前
asgi.py中的路由配置无需修改,路径ws/video_call/与转发规则匹配:
application = ProtocolTypeRouter({ "http": application, "websocket": AllowedHostsOriginValidator( AuthMiddlewareStack( URLRouter( [ path("ws/video_call/", VideoConsumers.as_asgi()), path('ws/ac/<str:uuid>/', Myconsumers.as_asgi()) ] ) ) ), })
- 重启Daphne服务确保配置生效:
systemctl restart daphne
验证步骤
- 使用
wscat工具测试WebSocket连接(需先安装npm install -g wscat):
wscat -c wss://www.kartikprajapati.com/ws/video_call/
连接成功会显示connected (press CTRL+C to quit)。
- 查看日志排查问题:
- Apache错误日志:
tail -f /var/log/apache2/error.log - Daphne日志:
journalctl -u daphne -f
额外排查点
- 检查Django
settings.py中的ALLOWED_HOSTS是否包含www.kartikprajapati.com - 确保服务器防火墙未拦截本地8001端口(同一服务器内转发无需开放外部端口)
- 验证
VideoConsumers类是否正确实现了connect()、disconnect()等必要方法
内容的提问来源于stack exchange,提问作者kartik prajapati
相关产品推荐
相关产品推荐

