flask+socketio+echarts3 服務器監控程序(基於後端數據推送)

本文地址:http://www.cnblogs.com/hhh5460/p/7397006.htmljavascript

說明

之前的那個例子的思路是後端監控數據存入數據庫;前端ajax定時查詢數據庫css

這幾天在看websocket。前端有一個js庫:socket.io.js,後端python也有不少庫實現了websocket,flask就有一個好用的擴展:flask-socketio。html

在參考了這裏以後,將前面那個例子改寫成後端後臺線程一旦產生數據,即刻推送至前端前端

好處是不須要前端ajax定時查詢,節省服務器資源java

項目一共兩個文件:python

  • app.py
  • templates/index.htmll

app.py

路由及後臺線程jquery

'''
服務器cpu監控程序

思路:後端後臺線程一旦產生數據,即刻推送至前端。
好處:不須要前端ajax定時查詢,節省服務器資源。

做者:hhh5460
時間:2017.8.19
'''
import psutil
import time

from threading import Lock

from flask import Flask, render_template, session, request
from flask_socketio import SocketIO, emit

# Set this variable to "threading", "eventlet" or "gevent" to test the
# different async modes, or leave it set to None for the application to choose
# the best option based on installed packages.
async_mode = None

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app, async_mode=async_mode)


thread = None
thread_lock = Lock()



# 後臺線程 產生數據,即刻推送至前端
def background_thread():
    """Example of how to send server generated events to clients."""
    count = 0
    while True:
        socketio.sleep(5)
        count += 1
        t = time.strftime('%M:%S', time.localtime()) # 獲取系統時間(只取分:秒)
        cpus = psutil.cpu_percent(interval=None, percpu=True) # 獲取系統cpu使用率 non-blocking
        socketio.emit('server_response',
                      {'data': [t, *cpus], 'count': count},
                      namespace='/test') # 注意:這裏不須要客戶端鏈接的上下文,默認 broadcast = True !!!!!!!


@app.route('/')
def index():
    return render_template('index.html', async_mode=socketio.async_mode)



# 與前端創建 socket 鏈接後,啓動後臺線程
@socketio.on('connect', namespace='/test')
def test_connect():
    global thread
    with thread_lock:
        if thread is None:
            thread = socketio.start_background_task(target=background_thread)




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

index.html

頁面文件git

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>ECharts3 Ajax</title>
    <script type="text/javascript" src="//cdn.bootcss.com/jquery/3.1.1/jquery.min.js"></script>
    <script type="text/javascript" src="//cdn.bootcss.com/socket.io/1.5.1/socket.io.min.js"></script>
    <!-- ECharts 3 引入 -->
    <script src="http://echarts.baidu.com/dist/echarts.min.js"></script>
</head>

<body>
    <!--爲ECharts準備一個具有大小(寬高)的Dom-->
    <div id="main" style="height:500px;border:1px solid #ccc;padding:10px;"></div>
    
    <script type="text/javascript">
    // 做者:hhh5460
    // 時間:2017.8.19
    //--- 折柱 ---
    var myChart = echarts.init(document.getElementById('main'));
    
    myChart.setOption({
        title: {
            text: '服務器系統監控'
        },
        tooltip: {},
        legend: {
            data:['cpu1','cpu2','cpu3','cpu4']
        },
        xAxis: {
            data: []
        },
        yAxis: {},
        series: [{
            name: 'cpu1',
            type: 'line',
            data: []
        },{
            name: 'cpu2',
            type: 'line',
            data: []
        },{
            name: 'cpu3',
            type: 'line',
            data: []
        },{
            name: 'cpu4',
            type: 'line',
            data: []
        }]
    });
    
    // 本人筆記本有四個cpu,讀者朋友請根據本身的狀況,相應修改!!
    // 五個全局變量:time、cpu一、cpu二、cpu三、cpu4
    var time = ["","","","","","","","","",""],
        cpu1 = [0,0,0,0,0,0,0,0,0,0],
        cpu2 = [0,0,0,0,0,0,0,0,0,0],
        cpu3 = [0,0,0,0,0,0,0,0,0,0],
        cpu4 = [0,0,0,0,0,0,0,0,0,0]
        

    //準備好統一的 callback 函數
    var update_mychart = function (res) { //res是json格式的response對象
        
        // 隱藏加載動畫
        myChart.hideLoading();
        
        // 準備數據
        time.push(res.data[0]);
        cpu1.push(parseFloat(res.data[1]));
        cpu2.push(parseFloat(res.data[2]));
        cpu3.push(parseFloat(res.data[3]));
        cpu4.push(parseFloat(res.data[4]));
        if (time.length >= 10){
            time.shift();
            cpu1.shift();
            cpu2.shift();
            cpu3.shift();
            cpu4.shift();
        }
        
        // 填入數據
        myChart.setOption({
            xAxis: {
                data: time
            },
            series: [{
                name: 'cpu1', // 根據名字對應到相應的系列
                data: cpu1
            },{
                name: 'cpu2',
                data: cpu2
            },{
                name: 'cpu3',
                data: cpu3
            },{
                name: 'cpu4',
                data: cpu4
            }]
        });
        
    };
    
    // 首次顯示加載動畫
    myChart.showLoading();

    
    // 創建socket鏈接,等待服務器「推送」數據,用回調函數更新圖表
    $(document).ready(function() {
        namespace = '/test';
        var socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port + namespace);
        
        socket.on('server_response', function(res) {
            update_mychart(res);
        });

    });
    
    </script>
</body>
</html>

效果圖

相關文章
相關標籤/搜索