这几天给django搭建的网站加了个用户通信和消息推送功能,本地运行完全没有任何问题,部署到服务器时折腾了很久,使用的框架是django,nginx,dphne等,django有个处理websocket的模块,django-channles,我们可以pip install xxx命令进行下载,服务器上下载环境命令如下所示
pip3 install django==2.2.4
pip3 install supervisor
pip3 install redis
pip3 install channels==2.4.0#(里面包含了daphne)
pip3 install channels-redis==2.4.2
pip3 install django-redis==5.2.0
这里注意下,下载channels时也会下载daphne了,本次使用supervisor来管理daphne,因为websocket通信用到asgi协议,而django默认是wsgi协议,要实现asgi,可以使用daphne服务器处理websocket请求,这里我用supervisor来管理daphne服务进程,让其监控它一直运行
root@VM-8-3-ubuntu:/home/ubuntu# cd /etc/supervisor/
root@VM-8-3-ubuntu:/etc/supervisor# ls
conf.d supervisord.conf
如上是安装supervisor的默认路径,注意这里,可以看见有conf.d supervisord.conf2个文件,supervisord.conf这个文件我们一般不动,我们可以进去看下其代码,
[unix_http_server]
file=/var/run/supervisor.sock ; (the path to the socket file)
chmod=0700 ; sockef file mode (default 0700)
[supervisord]
logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log)
pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
childlogdir=/var/log/supervisor ; ('AUTO' child log dir, default $TEMP)
; the below section must remain in the config file for RPC
; (supervisorctl/web interface) to work, additional interfaces may be
; added by defining them in separate rpcinterface: sections
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket
; The [include] section can just contain the "files" setting. This
; setting can list multiple files (separated by whitespace or
; newlines). It can also contain wildcards. The filenames are
; interpreted as relative to this file. Included files *cannot*
; include files themselves.
[include]
files = /etc/supervisor/conf.d/*.conf
直接看最后一行,supervisord.conf这个会自动读取conf.d里面的文件,因此我们想创建一个配置监控管理进程的文件可以直接从cond.d里面创建,而不用动这个supervisord.conf这个文件。切入conf.d,新建一个daphne.conf,里面配置代码如下
[program:daphne]
directory=/home/ubuntu/django_blogs/myblog
command=daphne -b 127.0.0.1 -p 8888 --proxy-headers myblog.asgi:application
# 在supervisord启动的时候也自动启动;
autostart = true
# 程序异常退出后自动重启;
autorestart = true
user = nobody
# 把stderr重定向到stdout,默认false;
redirect_stderr = true
# 标准日志输出;
stdout_logfile=out-daphne.log
# # 错误日志输出;
stderr_logfile=err-daphne.log
environment=ASPNETCORE__ENVIRONMENT=Production
user=root
注意下pragram后面的daphne和你的daphne.conf名对应起来,不然supervisord.conf找不到要执行的conf,这里的directory是你的django项目路径,command就是启动项目中asgi服务了,127.0.0.1是本机,端口是8888,确保这个端口没有被占用,同时服务器设置了这个端口的白名单,后面的配置就不用解释了。这里注意的是asgi.py是和settings.py同目录下,asgi.py代码如下
import os
import django
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myblog.settings")
django.setup()
import users.routing
from channels.http import AsgiHandler
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.security.websocket import AllowedHostsOriginValidator
application = ProtocolTypeRouter({
"http": AsgiHandler,
# Just HTTP for now. (We can add other protocols later.)
"websocket": AllowedHostsOriginValidator(
AuthMiddlewareStack(
URLRouter(
users.routing.websocket_urlpatterns
)
)
),
})
这里注意的是
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myblog.settings")
django.setup()
必须放到import users.routing之前,否则会报错。配置好了supservisor后,开始启动,命令如下
supervisord -c /etc/supervisor/supervisord.conf
可以查看888端口是否正常运行,如果没有正常运行,查看是否有错误日志,一个一个排查即可。接下来就是配置nginx了,进入nginx配置文件,命令如下
cd /usr/local/nginx/conf/
用vim打开nginx.conf,加入的代码如下所示
location /wss {
proxy_pass http://127.0.0.1:8888;
proxy_http_version 1.1;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_redirect off;
proxy_set_header X-Forwarded-Host $server_name;
}
由于我的配置了ssl证书,因此用wss协议,如果没有配置的则用ws即可,然后前端配置如下
const websocket = new WebSocket(
(window.location.protocol == 'https:' ? 'wss://' : 'ws://')
+ window.location.host
+ '/wss/chat/'
+ local_user
+ '/'
);
注意这里不用加端口,直接域名即可!,经过测试,配置成功!
点击此处登录后即可评论