Flask 之SocketIO库实现绘图表

Python
406
0
0
2023-02-12
标签   Flask

Flask 默认提供了针对WebSocket的支持插件from flask_socketio import SocketIO 直接通过pip命令安装即可导入使用,前端也需要引入socketIO库文件,其网站首页是:https://socket.io/

实现简单的数据通信

新建index.html

<!--name:index.html-->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script type="text/javascript" src="https://code.jquery.com/jquery-3.4.1.slim.min.js"></script>
    <script type="text/javascript" src="http://cdn.bootcss.com/socket.io/1.7.0/socket.io.min.js"></script>
</head>
<body>
<script type="text/javascript" charset="UTF-8">
    $(document).ready(function() {
        namespace = '/Socket';
        var socket = io.connect("http://" + document.domain + ":" + location.port + namespace);
        socket.emit("message",{"data":"hello lyshark"});  // 初始化完成后,发送一条消息.
        socket.on('response', function(recv) {
            console.log(recv.Data)
        });
    });
</script>
</body>
</html>

app.py

# name: app.py
from flask import Flask,render_template,request
from flask_socketio import SocketIO

async_mode = None
app = Flask(__name__)
app.config['SECRET_KEY'] = "lyshark"
socketio = SocketIO(app)

@app.route("/")
def index():
    return render_template("index.html")

# 出现消息后,率先执行此处
@socketio.on("message",namespace="/Socket")
def socket(message):
    print("接收到消息:",message['data'])
    for i in range(1,100):
        socketio.sleep(1)
        socketio.emit("response",          # 绑定通信
                      {"Data":i},           # 返回socket数据
                      namespace="/Socket")

# 当websocket连接成功时,自动触发connect默认方法
@socketio.on("connect",namespace="/Socket")
def connect():
    print("链接建立成功..")

# 当websocket连接失败时,自动触发disconnect默认方法
@socketio.on("disconnect",namespace="/Socket")
def disconnect():
    print("链接建立失败..")

if __name__ == '__main__':
    socketio.run(app,debug=True,host="0.0.0.0")

效果如下,程序会每隔一秒钟同步一次数据,在控制台中可看到。

img

使用SocketIO库绘制主机动态图形

前端第一个脚本,用于接收数据。

   <script type="text/javascript" charset="UTF-8">
        // 负责接收目标主机的CPU负载情况
        $(document).ready(function() {
            namespace = '/Socket';
            var socket = io.connect("http://" + document.domain + ":" + location.port + namespace);
            socket.emit("message",{"data":"hello lyshark"});  // 初始化完成后,发送一条消息.
            socket.on('response', function(recv) {
                //console.log(recv.Data);
                update(recv)   // 发送到update函数处理请求
            });
        });
    </script>

第二个脚本负责解析参数

    <script type="text/javascript" charset="UTF-8">
        // 负责对参数的解析
        var time =["","","","","","","","","",""];
        var cpu = [0,0,0,0,0,0,0,0,0,0];
        var update = function(recv){
            time.push(recv.Data[0]);
            cpu.push(parseFloat(recv.Data[1]));
            if(time.length >=10){
                time.shift();
                cpu.shift();
                console.log(time)
                display(time,cpu)  // 调用绘图函数
            }
        };
    </script>

最后一段代码负责,调用百度绘图库,进行图形的呈现。

    <div id="main" style="height:500px;width:1200px;border:1px solid #eecc11;padding:10px;"></div>
    <script type="text/javascript" charset="UTF-8">
            var display = function(time,cpu){
                // 负责初始化绘图画布
                var myChart = echarts.init(document.getElementById('main'));
                myChart.setOption({
            title: {
                text: '监控系统CPU资源'
            },
            tooltip: {},
            xAxis: {
                data: []
            },
            yAxis: {},
            series: [{
                name: 'cpu',
                type: 'line',
                data: []
            }]
        });
            // 下方就是给指定字段填充数据
            myChart.setOption({
                xAxis: {
                    data: time
                },
                series: [{
                    name: 'cpu', // 根据名字对应到相应的系列
                    data: cpu
                }]
            });
        };
        // 首次显示加载动画
        myChart.showLoading();
    </script>

后端直接区数据并发送给前台 app.py 需要注意flask 开头写法不再是app()而要改成 socketio.run(app,debug=True,host="0.0.0.0")才可以

# name: app.py
from flask import Flask,render_template,request
from flask_socketio import SocketIO
import time,psutil
async_mode = None
app = Flask(__name__)
app.config['SECRET_KEY'] = "lyshark"
socketio = SocketIO(app)

@app.route("/")
def index():
    return render_template("index.html")

# 出现消息后,率先执行此处
@socketio.on("message",namespace="/Socket")
def socket(message):
    print("接收到消息:",message['data'])
    while True:
        socketio.sleep(60)
        data = time.strftime("%M:%S",time.localtime())
        cpu = psutil.cpu_percent(interval=None,percpu=True)
        socketio.emit("response",
                      {"Data":[data,cpu]},
                      namespace="/Socket")

if __name__ == '__main__':
    socketio.run(app,debug=True,host="0.0.0.0")

最终统计效果如下所示,当然也可以批量统计存入数据库,需要的时候直接调用绘图。

img

百度绘图库(官方地址):https://www.echartsjs.com/zh/index.html

Ajax实现定时器 另一种实现定时器定时获取数据的方法

<button type="button" class="btn btn-success" id="btn">定时</button>

<script>
    $("#btn").click(function(){
        var count = setInterval(function(){
            $.ajax({
                url:"/_get/",
                type:"POST",
                contentType:"application/json;charset=utf-8",
                success:function (data) {
                    var data = JSON.parse(data);
                    console.log("当前进度:" + data.flag);
                    $("#1111").width(data.flag);
                    if (data.flag == 100){
                        clearInterval(count);
                    }
                }
            })
            },2000);  // 每两秒执行一次
        });
</script>