本节内容是通过 Nginx 与 uWSGI 将项目部署至 AcWing 平台上,同时修复在 AcApp 小窗口上存在的部分 BUG。
现在我们需要将之前在网页上运行的项目部署至 AcWing 上,让其前后端分离,一个后端可以对应多个前端。
如果要将网站修改为 HTTPS 协议,需要先购买一个域名,然后申请证书,还需要进行备案,非常麻烦。在 AcWing 上线 App 已具备域名和证书。
1. 增加容器的映射端口80与443
由于创建后的容器不方便增加新的端口映射,因此我们先将原容器保存成镜像后再生成一个新的容器。
首先需要将容器中正在运行的任务全部关闭,然后登录运行容器的服务器,执行以下命令:
1 | docker commit ubuntu_django ubuntu_django:1.0 # 将容器ubuntu_django打包成镜像ubuntu_django,版本号为1.0 |
此时如果无法远程连接容器可以按照 Django 学习笔记-配置 Docker、Git 环境与项目创建文章创建一个 hosts.allow
文件。
接着去云服务器的控制台,在安全组配置中开放80和443端口。
2. 安装Nginx
(1)安装依赖包(安装均在根用户 root
下进行):
1 | apt install curl gnupg2 ca-certificates lsb-release ubuntu-keyring |
(2)安装 Nginx:
1 | apt-get update |
(3)查看版本号:
1 | nginx -v |
(4)启动 Nginx 以及查看是否在运行中:
1 | systemctl start nginx |
如果报错:System has not been booted with systemd as init system (PID 1). Can't operate. Failed to connect to bus: Host is down
,可以参考这篇文章:System has not been booted with systemd as init system (PID 1). Can‘t operate. 问题解决方法,简而言之就是用以下指令代替:
1 | service nginx start |
3. 写入AcWing配置信息
配置信息在 AcWing 平台上可以查看,按以下步骤将信息复制到项目的配置文件中即可:
- 将
nginx.conf
中的内容写入服务器/etc/nginx/nginx.conf
文件中。如果 Django 项目路径与配置文件中不同,注意修改路径。 - 将
acapp.key
中的内容写入服务器/etc/nginx/cert/acapp.key
文件中(cert
目录需要自己创建)。 - 将
acapp.pem
中的内容写入服务器/etc/nginx/cert/acapp.pem
文件中。
然后启动 Nginx 服务:
1 | sudo /etc/init.d/nginx start |
如果启动不成功可以重新加载一下 Nginx 的配置文件即可看到错误在哪:
1 | sudo nginx -s reload |
4. 修改Django项目的配置
- 打开
settings.py
文件:- 将分配的域名添加到
ALLOWED_HOSTS
列表中。注意只需要添加https://
后面的部分。 - 令
DEBUG = False
。
- 将分配的域名添加到
- 归档
static
文件:- 在项目根目录下执行:
python3 manage.py collectstatic
,执行完后可以看到生成了一份game
中的static
目录。
- 在项目根目录下执行:
5. 配置uWSGI
WSGI(Web Server Gateway Interface)是为 Python 语言定义的 Web 服务器和 Web 应用程序或框架之间的一种简单而通用的接口。网关(Gateway)的作用就是在协议之间进行转换。很多框架都自带了 WSGI Server,比如 Flask、Django 等。当然性能都不好,自带的 Web Server 更多的是测试用途,发布时则使用生产环境的 WSGI Server 或者是联合 Nginx 做 uWSGI。
uWSGI 是一个 Web 服务器,它实现了 WSGI、uwsgi、HTTP 等协议。Nginx 中 HttpUwsgiModule
的作用是与 uWSGI 服务器进行交换。
要注意 WSGI、uwsgi、uWSGI 这三个概念的区分:
- WSGI 的内容之前已经讲过了,是一种通信协议。
- uwsgi 同 WSGI 一样是一种通信协议。
- uWSGI 则是实现了 uwsgi 和 WSGI 两种协议的 Web 服务器。
uwsgi 协议是一个 uWSGI 服务器自有的协议,它用于定义传输信息的类型(type of information),每一个 uwsgi packet
前 4byte
为传输信息类型描述,它与 WSGI 相比是两样东西。
为什么有了 uWSGI 还需要 Nginx?因为 Nginx 具备优秀的静态内容处理能力,然后将动态内容转发给 uWSGI 服务器,这样可以达到很好的客户端响应。
现在用户通过80/443端口访问 Nginx,而 Nginx 与 Django 项目之间还需要一个桥梁就是 uWSGI。
在 Django 项目中添加 uWSGI 的配置文件:scripts/uwsgi.ini
,内容如下:
1 | [uwsgi] |
由于使用 uwsgi
命令启动项目后原来的公网 IP 就无法访问了,因此需要对 web.html
中 CSS、JS 的链接地址进行修改:
1 | {% load static %} |
然后启动 uwsgi
服务(代替 python3 manage.py runserver 0.0.0.0:8000
):
1 | uwsgi --ini scripts/uwsgi.ini |
在 AcWing 填写完应用的剩余信息即可发布。
6. 部分BUG修复
在 AcWing 中打开应用时可以发现鼠标右键点击的位置不对,这是因为之前我们默认游戏的画布在左上角,而开启小窗口后画布就不在左上角了,我们移动小球时用的 e.clientX/Y
表示的是整个屏幕的坐标,而小球的位置坐标本身是画布中的相对坐标。
Canvas 中的 getBoundingClientRect
函数可以获得当前视窗在浏览器中的位置以及自身占据的空间的大小,left
表示窗口左侧边框距离浏览器视窗左侧的距离,top
表示窗口顶侧边框距离浏览器视窗顶侧的距离,right
表示窗口右侧边框距离浏览器视窗左侧的距离,bottom
表示窗口底侧边框距离浏览器视窗顶侧的距离:
因此我们将鼠标点击的坐标分别减去 left
和 top
即可映射到当前视窗内,在 Player
类中进行修改:
1 | class Player extends AcGameObject { |
注意现在我们的项目为发行版本,修改完静态文件且打包完后还需要去项目根目录执行:python3 manage.py collectstatic
,此时会问你是否要覆盖,输入 yes
即可。我们同样也可以修改之前的打包脚本 compress_game_js.sh
,在其后面添加一行:echo yes | python3 manage.py collectstatic
。
由于游戏有菜单界面,应该在从菜单进入游戏后才开始计算窗口大小,因此我们需要把 AcGamePlayground
的初始化放在 show
函数中执行:
1 | class AcGamePlayground { |
最后我们需要对菜单页面进行修改,在小窗口中的菜单页面不太美观,需要让其适应窗口大小,应该用小窗口的相对距离来表示,对 game.css
进行修改:
1 | .ac_game_menu { |
上一章:Django学习笔记-创建游戏界面。
下一章:Django学习笔记-用户名密码登录。