当你的django项目中使用channels增加了websocket功能的时候,在使用runserver命令启动时,既可以访问http请求,又可以访问websocket请求。但是当你使用uWSGI+nginx的来启动项目的时候,你会发现http请求可用,但是websocket请求永远是404的错误。这是为什么呢?
因为在我们的标准生产环境部署中,使用的事WSGI协议来启动的我们的项目,也就是使用的wsgi.py这个文件来对接的uWSGI服务器。但是我们channels使用的ASGI协议,在我们使用uWSGI来启动项目的时候,关于ASGI的一些配置他就找不到了。这就导致了你所有的websocket请求都是404。在查阅了大量的资料和阅读了官方文档以后终于解决了这个问题。
这个问题的解决有两种方案:
-
启用uWSGI来处理所有的http请求,另外开启一个daphne服务来处理websocket请求。这样的好处是按照请求类型分流,两种请求方式互不干扰。
-
另外一种则是启用daphne服务来处理http和websocket这两种请求。在daphne服务内部他会根据请求类型的不同分开处理。让你既可以访问websocket又可以访问http。
安装Daphne
pip install daphne
在setting.py同级的目录下新建一个asgi.py文件
""" ASGI entrypoint. Configures Django and then runs the application defined in the ASGI_APPLICATION setting. """ import os import django from channels.routing import get_default_application os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myproject.settings") django.setup() application = get_default_application()
daphne -b 0.0.0.0 -p 8000 myproject.asgi:application
这种方式只是在后台启动了你的项目,我们为了保证项目的稳定性,保证项目在意外死亡以后可以迅速的重启,我们来使用supervisor来管理我们的daphne服务。
-
作用:它可以很方便的监听、启动、停止、重启一个或多个进程。
-
用Supervisor管理的进程,当一个进程意外被杀死,supervisort监听到进程死后,会自动将它重新拉起
-
很方便的做到进程自动恢复的功能,不再需要自己写shell脚本来控制。
-
说白了,它真正有用的功能是俩个将非daemon(守护进程)程序变成deamon方式运行对程序进行监控,当程序退出时,可以自动拉起程序。
-
但是它无法控制本身就是daemon的服务。
yum install epel-release
yum install supervisor
不要使用pip下载supervisor,因为系统有python2.7和python3.6两个版本,有时候会因为版本问题倒是supervisor启动错误。而且pip的supervisor的安装和使用方式也更为繁琐一些。
在/etc/supervisord.d/文件夹下面配置被管理的服务的配置,然后启动supervisor即可管理该服务。
下面使用supervisor来管理我们dephne服务
[program:asgi] directory=/code/shiyanloupro/ command=daphne -b 0.0.0.0 -p 8000 --proxy-headers shiyanloupro.asgi:application autostart=true autorestart=true stdout_logfile=/tmp/websocket.log #日志 redirect_stderr=true