socketio项目部署

在开发期间,后台服务使用的是 Flask 自带的 development server,该服务不支持 websocket 协议,只支持 pollling 协议。

在项目上线时,我们需要使用生产环境的 web server,如 gunicorn,uwsgi,以及能够支持 websocket 协议的网络库: eventlet 或 gevent。

gunicorn + eventlet 开启服务

这里使用 gunicorn + eventlet,需要修改如下部分:

(1)创建 socketio 服务时指定 async_mode 为 eventlet:

1
sio = SocketIO(cors_allowed_origins='*', async_mode='eventlet')

(2)为避免使用 polling 协议,socketio 客户端指定协议为 websocket:

1
2
3
4
5
const socket = io("https://10.0.0.76:5000", {
autoConnect: true,
reconnectionDelay: 2000,
transports: ["websocket"]
});

现在可以通过以下指令开启服务(https):

1
gunicorn -b 10.0.0.76:5000 --certfile CA/xxx.crt --keyfile CA/xxx.key --worker-class eventlet -w 1 app:app

第一个 app 指的是定义 application 实例的文件(app.py),第二个 app 指定的是 application 实例本身。

为了方便,我们用文件的形式来启动 gunicorn:

新建 gunicorn.conf.py,向其中添加如下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 并行工作进程数
workers = 1
# 指定每个工作者的线程数
threads = 2
# 监听内网端口5000
bind = ':5000'
# 工作模式协程
worker_class = 'eventlet'
# 设置最大并发量
worker_connections = 2000
# 设置访问日志和错误信息日志路径
accesslog = './log/gunicorn_acess.log' # 记录访问服务器的用户信息
errorlog = './log/gunicorn_error.log' # 记录服务器运行日志
# 标准输出
accesslog = '-'
errorlog = '-'
#设置这个值为true 才会把打印信息记录到错误日志里
capture_output = True
# 设置日志记录水平
loglevel = 'warning'
# 文件更改后是否重启
reload = True

通过以下命令启用配置文件:

1
gunicorn -c gunicorn.conf.py app:app
nginx 反向代理

将 https 代理到 http。

向 nginx 配置文件中添加如下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
server {
...
root html;
location / {
try_files $uri $uri/ /index.html;
}

# https 请求反向代理
location /api {
proxy_pass http://127.0.0.1:5000
}

# socketio 反向代理
location /socket.io {
proxy_http_version 1.1;
proxy_buffering off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_pass http://127.0.0.1:5000/socket.io;
}

}

此时前端接口的端口号不再是 5000,而是默认 443。