前言
昨天写了这篇最细节的Flask+echarts+mysql+自动刷新升级版(websocket),前后端都是放到一起的,今天做一个分离版的,通过vue写前端。
一、vue2+websocket部署
基本部署就不多做赘述了,网上资料很多,新建一个vue项目,用pycharm打开,安装了jquery,先测试了一下,处理思路如下:
<template>
<div>
<input type="text" placeholder="请输入消息" v-model="msg" />
<button @click="handle">发送</button>
</div>
</template>
<script>
const ws = new WebSocket('ws://127.0.0.1:8000/test');
export default {
name: "Home",
data(){
return{
msg: '',
username:'',
msgList:[]
}
},
mounted() {
this.username = localStorage.getItem('username');
if(!this.username){
// this.$router.push('/');
}
// 绑定四个事件处理函数
ws.addEventListener('open', this.handleWsOpen.bind(this), false);
ws.addEventListener('close', this.handleWsClose.bind(this), false);
ws.addEventListener('error', this.handleWsError.bind(this), false);
ws.addEventListener('message', this.handleWsMessage.bind(this), false);
},
methods:{
// 方法的预处理
handle(){
const msg = this.msg;
if(!msg.trim().length){
}
},
handleWsOpen(e){
console.log('websocket Open!', e);
},
handleWsClose(e){
console.log('websocket Close!', e);
},
handleWsError(e){
console.log('websocket Error!', e);
},
handleWsMessage(e){
console.log('websocket Message!', e);
}
}
}
</script>
结果如下,由于没部署服务端,导致是这样。
二、vue2+websocket+flask
由于我自己在测试的过程中遇到了很多问题,先讲一讲逻辑
现在的前后端分离页面和接口不是一个程序,例如本例中
前端页面为localhost:8080
后端接口为localhost:5000
如下图:当我启动前端程序的时候报错第二个,启动后端服务器的时候报错第一个。
1.第一个错误就是CORS跨域错误,我们知道协议,域名 ,端口 要一样才算一个站点,这两个端口号不同,因此会出现跨域错误。
2.第二个错误就是服务器没有和前端连接。
因此在写服务端(flask)的时候要注意添加跨域请求处理:
socketio = SocketIO()
socketio.init_app(app, cors_allowed_origins='*')
以下为源码,细节部分写在注解中:
服务器app_vue.py:
from flask import Flask, render_template
from flask_cors import CORS
from flask_socketio import SocketIO, emit, send
from threading import Lock
async_mode = None
app = Flask(__name__)
CORS(app) # 跨域问题
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO()
socketio.init_app(app, cors_allowed_origins='*')
thread = None
thread_lock = Lock()
# @app.route('/')
# def index():
# return render_template('test.html')
@socketio.on('conn', namespace='/test')
def test_connect():
print('connect')
socketio.emit('server_response', {'data': 'I love u!'}, namespace='/test')
if __name__ == '__main__':
socketio.run(app, host='127.0.0.1', port='5000', debug=True)
客户端vue部分:
- main.js引入socketio:
import VueSocketIO from 'vue-socket.io'
import socketIO from 'socket.io-client'
Vue.use(new VueSocketIO({
debug: true,
// "ws://域名:端口号/namespace"
connection: socketIO.connect('ws://127.0.0.1:5000/test', {
autoConnect:false
})
}))
- vue
<template>
<div class="wrap">
<button @click="socketEmit">连接Socket</button>
<button @click="socketSendmsg">发送数据</button>
</div>
</template>
<script>
export default {
data() {
return {
data:{},
}
},
methods:{
socketEmit(){
// 开始连接socket
this.$socket.open();
},
// 发送消息
socketSendmsg(){
console.log('现在开始发送消息')
// conn 是与后端约定好的名称
this.$socket.emit('conn');
// server_response 是前端传过来的信息说明
this.sockets.subscribe('server_response', (res) => {
console.log(res.data);
})
}
},
sockets:{
connect: function () {
console.log('连接成功')
},
disconnect: function () {
console.log('断开连接')
},
reconnect: function () {
console.log('重新连接')
},
},
beforeDestroy() {
// 关闭socket
// this.sockets.unsubscribe('conn');
this.$socket.close();
}
}
</script>
需要注意的是前后端启动不分顺序,但flask启动必须通过命令行终端启动,不要通过pycharm编译器启动,在这里先启动服务器:python app_vue.py
,再启动客户端:npm run dev
,结果如下:
三、加入线程传值画图
第一步:测试服务器不断读取数据库传输数据给客户端,代码在这篇Flask+echarts+mysql+自动刷新升级版(websocket),这里展示结果:
有个问题,python在命令行运行的时候模板会出现找不到的情况,在这里我说明下:
1.如果是非自定义的包,请直接”pip install 包“ 下载。
2.如果是自定义的包,如下
import sys
// sys.path.append("想要引入包的绝对路径")
sys.path.append("E:\pycharm2020\projects\WebsocketTest\db")
服务器部分:
app_create_vue.py和db_create.py在前言文献中找。
命令行分别运行python app_create_vue.py
和python db_create.py
。
前端部分:
- 在main.js中引入echarts,没有这个包的请下载4版本的,5版本有很多兼容性问题,
npm install echarts@4.8.0 --save
import echarts from "echarts";
Vue.prototype.$echarts = echarts;
- vue部分,直接上代码
<template>
<div class="wrap">
<button @click="socketEmit">连接Socket</button>
<button @click="socketSendmsg">发送数据</button>
<div id="main" style="height:500px;border:1px solid #ccc;padding:10px;"></div>
</div>
</template>
<script>
import echarts from "echarts";
export default {
data() {
return {
data:{},
}
},
methods:{
socketEmit(){
// 开始连接socket
this.$socket.open();
},
// 发送消息
socketSendmsg(){
console.log('现在开始发送消息')
// conn 是与后端约定好的名称
this.$socket.emit('conn');
// 先画好图,然后以下读取的数据不断push进图中
var myChart = echarts.init(document.getElementById('main')) // 拿到一个实例
var record_t = ["","","","","","","","","",""], temperature = [0,0,0,0,0,0,0,0,0,0]
myChart.setOption({
title: {
text: 'websocket温度测试'
},
tooltip: {},
legend: {
data:['temperature']
},
xAxis: {
data: []
},
yAxis: {},
series: [{
name: 'temperature',
type: 'line',
data: []
}]
});
// server_response 是前端传过来的信息说明
this.sockets.subscribe('server_response', (res) => {
// 测试打印
console.log(res.data[0]);
console.log(res.data[1]);
// 每次获取到最新数据之后应该是做出对图标的插入操作
record_t.push(res.data[0]);
console.log(record_t);
temperature.push(parseFloat(res.data[1]));
console.log(temperature);
if(record_t.length >= 10){
record_t.shift();
temperature.shift();
}
myChart.setOption({
xAxis: {
data: record_t
},
series: [{
name: 'temperature', // 根据名字对应到相应的系列
data: temperature
}]
})
})
}
},
sockets:{
connect: function () {
console.log('连接成功')
},
disconnect: function () {
console.log('断开连接')
},
reconnect: function () {
console.log('重新连接')
},
},
beforeDestroy() {
// 关闭socket
// this.sockets.unsubscribe('conn');
this.$socket.close();
}
}
</script>
结果如图,前后端分离完成:
结语
前后端分离有关数据处理的demo就已经结束了,后期将会把这三篇后续更新完,并且优化,应用到养殖实体。