Flask+echarts+mysql+websocket+vue实现前后端分离数据可视化刷新

前言

昨天写了这篇最细节的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部分:

  1. 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
        })
    }))
    
  2. 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.pypython db_create.py

前端部分:

  1. 在main.js中引入echarts,没有这个包的请下载4版本的,5版本有很多兼容性问题,npm install [email protected] --save

    import echarts from "echarts";
    Vue.prototype.$echarts = echarts;
    
  2. 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就已经结束了,后期将会把这三篇后续更新完,并且优化,应用到养殖实体。
三维交互可视化平台(智慧海上牧场平台)学习开发之Vue(一)
三维交互可视化平台(智慧海上牧场平台)学习开发之Flask+Vue+Mysql(二)
三维交互可视化平台(智慧海上牧场平台)学习开发Flask+Vue+Echarts+Mysql实战(三)
如果对您有帮助的话,三连支持一下,谢谢!

猜你喜欢

转载自blog.csdn.net/weixin_44165950/article/details/127240607