Vue Vuesocketio
VueSocketio的前端实现与大坑
前端实现
首先,如果全局初始化socket实例的话,在main.js中声明即可。 以下是在具体vue组件中使用的情况:
import VueSocketio from 'vue-socket.io'
import Vue from 'vue'
Vue.use(new VueSocketio({
debug: true,
// connection: 'ws://10.60.82.83/lptslog',
connection: req_url_us_ws + '/lptslog',
options: {
// path: '/lptslog',
autoConnect: false,
transports: ['websocket', 'xhr-polling', 'jsonp-polling']
}
}))
这个Vue-Socket.io官方文档并没有提到*transports*是干啥的,它给的例子是:
import Vue from 'vue'
import store from './store'
import App from './App.vue'
import VueSocketIO from 'vue-socket.io'
Vue.use(new VueSocketIO({
debug: true,
connection: 'http://metinseylan.com:1992',
vuex: {
store,
actionPrefix: 'SOCKET_',
mutationPrefix: 'SOCKET_'
},
options: { path: "/my-app/" } //Optional options
}))
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
你说说看,哪里提到*transports*了?
而我本地的vue项目启动后,也可以和flask后端的socketio正常连接和通信,然而当我部署到测试服务器的docker中后,完全不能够建立连接,一直在报400 Bad Request,我尝试调整nginx无数次,但是完全不好使,直到无意间加上了这个*transports*参数!!!
原来这个库依赖SocketIO,而这个SocketIO实例化是需要*transports*的!!!
https://socket.io/docs/client-api/
// With websocket transport only
// By default, a long-polling connection is established first, then upgraded to “better” transports (like WebSocket). If you like to live dangerously, this part can be skipped:
const socket = io({
transports: ['websocket']
});
// on reconnection, reset the transports option, as the Websocket
// connection may have failed (caused by proxy, firewall, browser, ...)
socket.on('reconnect_attempt', () => {
socket.io.opts.transports = ['polling', 'websocket'];
});
这尼玛不写明白了谁知道啊!!!
关于nginx配置和dockerfile
vue项目部署到docker上时,为了保险起见和能够灵活配置,步骤如下:
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
# add_header Access-Control-Allow-Origin "*";
# proxy_http_version 1.1;
# proxy_set_header Upgrade $http_upgrade;
# proxy_set_header Connection "upgrade";
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
其实很简单,就是从docker官网nginx镜像中扒一个基础配置出来,每次部署docker时挂载进去,dockerfile如下:
FROM daocloud.io/nginx
COPY dist/ /usr/share/nginx/html
RUN rm /etc/nginx/conf.d/default.conf
CMD ["nginx", "-g", "daemon off;"]
在服务器部署时使用的shell脚本如下:
updatedocker.sh
#!/bin/bash
echo '停止容器 - 删除容器 - 删除镜像'
docker stop dist_nginx_1 && docker rm dist_nginx_1 && docker rmi dist_nginx
echo '构建容器 - 启动容器'
docker build -t dist_nginx . && docker run -d -p 80:80 -v /home/odindist/default.conf:/etc/nginx/conf.d/default.conf --name dist_nginx_1 dist_nginx
本地vue项目build后在odindist目录(git上传到服务器的目录)下执行脚本:
cp -rf ../dist/ ./dist/ && cp -f ../src/assets/favicon.ico ./dist/favicon.ico
用来复制dist文件和更新网站ico
flask部署dockerfile
FROM base_docker:v1
MAINTAINER xxx@xxx.com
COPY . /home/odin/
WORKDIR /home/odin
RUN pip install -r requirements.txt
EXPOSE 8888
ENV FLASK_CONFIG prod
ENTRYPOINT ["gunicorn","--config","/home/odin/gunicorn_config.py","manage:app"]
flask-socket.io
# odin-ws/raw/master/application/__init__.py
import os
import logging
from flask import Flask
from flask_cors import CORS
from flask_sqlalchemy import SQLAlchemy
from flask_socketio import SocketIO
# from flask_sockets import Sockets
from utils.log import MyLogging
import eventlet
# eventlet.monkey_patch()
app = Flask(__name__)
app.config.from_object("config.{}".format(os.getenv('FLASK_CONFIG') or "dev"))
db = SQLAlchemy(app)
CORS(app)
socketio = SocketIO(app, cors_allowed_origins='*', async_mode='eventlet', engineio_logger=True)
# 生成自定义日志对象
my_logging = MyLogging()
stdout_handler = my_logging.get_stdout_handler()
file_handler_info = my_logging.get_file_handler("log/app_output_info.log", logging.INFO)
file_handler_error = my_logging.get_file_handler("log/app_output_error.log", logging.ERROR)
file_handler_warning = my_logging.get_file_handler("log/app_output_warning.log", logging.WARNING)
# 清空默认日志对象
app.logger.handlers.clear()
# 设置全局日志等级
app.logger.setLevel(logging.DEBUG)
# 添加自定义日志对象
app.logger.addHandler(stdout_handler)
app.logger.addHandler(file_handler_info)
app.logger.addHandler(file_handler_error)
app.logger.addHandler(file_handler_warning)