websocket前后端分离demo(vue-socket.io + flask-socketio + nginx)
目录1 vue-socket.io 配置1.1`main.js` 文件1.2`app.vue`2 flask-socketio 配置2.1 demo 代码2.2 启动3 nginx 配置4 相关问题基本 demo,列出重要的一些问题1 vue-socket.io 配置1.1main.js 文件...import VueSocketio from 'vue-socket.i...
文章目录
基本 demo,列出重要的一些问题
1 vue-socket.io 配置
1.1 main.js
文件
...
import VueSocketio from 'vue-socket.io'
Vue.use(new VueSocketio({
debug: true,
connection: 'https://domain/chatroom'
}))
...
注意点:
-
chatroom
为后端flask-socketio
中namespace
(此处为静态命令空间,动态命令空间设置较为复杂)根据官方文档,可以额外设置
options: {path: '/chatroom'}
,则后端nginx
中/socketio
改为/chatroom
;不设置,后端默认/socketio
1.2 app.vue
<script>
import axios from 'axios'
export default{
data() {
return {
messages: []
}
},
created() {
const url = 'https://domain/chatroom/index'
axios({
method: 'get',
url: url,
data: {
msg: 'hello'
}
}).then(res => {
console.log(res)
})
},
sockets: {
connect: function() {
console.log('socket connected')
},
# 监听后端传来数据(自定义提示)
response: function(res) {
this.$message.success(res.msg)
},
# 监听后端传来数据(自定义消息)
chat_message: function(msg) {
this.messages.push(msg)
},
methods: {
onMsgSubmit(msg){
# 用户点击,提交用户输入
this.$socket.emit('user_input', msg)
}
}
}
}
</script>
- 创建页面时,
axios
进行HTTP/HTTPS
请求 sockets
中自动创建WebSocket
连接,response
和chat_message
分别用来监听后端不同回复,并分别做处理onMsgSubmit
用户输入后,向后端user_input
传输数据
2 flask-socketio 配置
2.1 demo 代码
from threading import Lock
from flask import Flask, request
from flask_socketio import SocketIO, emit, join_room, \
leave_room, close_room, rooms, disconnect
from flask_cors import CORS
app = Flask(__name__)
app.config['SECRET_KEY'] = 'chatroom'
CORS(app, supports_credentials=True)
socketio = SocketIO(app, cors_allowed_origins="*")
def background_chat(msg, sid):
for _ in range(3):
socketio.emit('chat_message', {'content': msg + "?"},
namespace='/chatroom',
room=sid)
socketio.sleep(3)
@app.route('/index', methods=['GET'])
def index():
return 'welcome to the chatroom!'
@socketio.on('join', namespace='/chatroom')
def join_chat(message):
"""创建聊天室
"""
join_room(request.sid)
thread = socketio.start_background_task(background_chat, msg,request.sid)
emit('response', {'msg': '创建聊天室成功'})
@socketio.on('leave', namespace='/chatroom')
def leave_chat(message):
"""离开聊天室,仅删除当前用户
"""
@socketio.on('close', namespace='/chatroom')
def close_chat(message):
"""关闭聊天室,将所有用户移出
"""
@socketio.on('user_input', namespace='/chatroom')
def user_input(message):
"""获取用户输入
"""
sid = request.sid
# TODO
@socketio.on('connect', namespace='/chatroom')
def connect():
"""创建socket链接
用户进入浏览器页面,自动加入
"""
print('connect', request.sid)
@socketio.on('disconnect', namespace='/chatroom')
def disconnect():
"""关闭socket链接
用户关闭浏览器页面,自动退出
"""
print('Client disconnected', request.sid)
if __name__ == '__main__':
socketio.run(app, debug=True, host="127.0.0.1", port=5000)
-
跨域,在
flask
和flask-socketio
中设置后,nginx
中不用再设置 -
request.sid
获取session_id
,每个用户单独一个聊天室 -
向特定用户
sid
回复socketio.emit('chat_message', {},namespace='/chatroom',room=sid)
2.2 启动
gunicorn -b 127.0.0.1:8211 -k eventlet -w 1 wss_app:app
pip install eventlet
-w
必须设为 1,否则报错invalid session
3 nginx 配置
server {
listen 80;
server_name api.mcc.khay.site;
rewrite ^(.*)$ https://$host$1 permanent;
}
server {
listen 443 ssl http2;
server_name domain;
access_log /var/log/nginx/domain.access.log;
error_log /var/log/nginx/domain.error.log;
ssl on;
ssl_certificate /etc/letsencrypt/live/domain/cert.pem;
ssl_certificate_key /etc/letsencrypt/live/domain/privkey.pem;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location /static {
alias /var/www/mcc/website/static;
}
location /chatroom/ {
include proxy_params;
proxy_pass http://127.0.0.1:8211/;
}
location /socket.io {
#add_header Access-Control-Allow-Credentials true;
include proxy_params;
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:8211/socket.io;
}
}
注意点:
- 同一个
flask
应用中,HTTP/HTTPS
和WebSocket
需要路由到不同端口 HTTP/HTTPS
通过domain/chatroom/xxx
访问,其中/chatroom/
中后一个/
不能省略WebSocket
通过domain/socket.io
访问,/socket.io
后面不需要添加/
4 相关问题
-
跨域设置
-
nginx
和flask/flask-socketio
只需要其中一个设置即可 -
nginx
设置WebSocket
各种报错,未成功;HTTP/HTTPS
设置location / { root /var/www/html; index index.html index.htm; add_header Access-Control-Allow-Origin * always; add_header Access-Control-Allow-Headers "DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Cont ent-Type,Authorization, user-id" always; add_header Access-Control-Allow-Methods "GET, POST, OPTIONS, PUT, PATCH, DELETE, HEAD" always; add_header Access-Control-Max-Age 86400 always; if ($request_method = 'OPTIONS') { return 204; } proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://127.0.0.1:8200/; }
- 如果
Header
中携带其他数据,直接在Access-Control-Allow-Headers
中添加即可
- 如果
-
flask/flask-socketio
设置pip install flask-cors
from flask_cors import CORS ... app = Flask(__name__) CORS(app, supports_credentials=True) # HTTP/HTTPS 跨域 socketio = SocketIO(app, cors_allowed_origins="*") # websocket 跨域
-
-
Invalid session
-
gunicorn
其中-w
(即workers
) 必须设为1
Due to the limited load balancing algorithm used by gunicorn, it is not possible to use more than one worker process when using this web server. For that reason, all the examples above include the
-w 1
option.
-
5 参考文档
参考官方文档,Github issues 即可
更多推荐
所有评论(0)