本文地址:http://www.cnblogs.com/hhh5460/p/7397006.htmljavascript
之前的那個例子的思路是後端監控數據存入數據庫;前端ajax定時查詢數據庫。css
這幾天在看websocket。前端有一個js庫:socket.io.js,後端python也有不少庫實現了websocket,flask就有一個好用的擴展:flask-socketio。html
在參考了這裏以後,將前面那個例子改寫成後端後臺線程一旦產生數據,即刻推送至前端。前端
好處是不須要前端ajax定時查詢,節省服務器資源。java
項目一共兩個文件:python
路由及後臺線程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)
頁面文件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>