Flask SocketIO 实现动态绘图
Flask-SocketIO 是基于 Flask 的一个扩展,用于简化在 Flask 应用中集成 WebSocket 功能。WebSocket 是一种在客户端和服务器之间实现实时双向通信的协议,常用于实现实时性要求较高的应用,如聊天应用、实时通知等,使得开发者可以更轻松地构建实时性要求较高的应用。通过定义事件处理函数,可以实现双向实时通信,为应用提供更加丰富和实时的用户体验。
前端参数拼接
Flask 提供了针对WebSocket的支持插件flask_socketio直接通过pip命令安装即可导入使用,同时前端也需要引入SocketIO.js库文件。
如下代码通过ECharts图表库和WebSocket技术实现了一个实时监控主机CPU负载的动态折线图。通过WebSocket连接到Flask应用中的Socket.IO命名空间,前端通过实时接收后端传来的CPU负载数据,动态更新折线图,展示1分钟、5分钟和15分钟的CPU负载趋势。同时,通过控制台打印实时数据,实现了方便的调试和监控功能。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="https://www.lyshark.com/javascript/jquery/3.5.1/jquery.min.js"></script>
<script type="text/javascript" src="https://www.lyshark.com/javascript/socket.io/socket.io.min.js"></script>
<script type="text/javascript" src="https://www.lyshark.com/javascript/echarts/5.3.0/echarts.min.js"></script>
</head>
<body>
<div id="Linechart" style="height:500px;width:1200px;border:1px solid #673ab7;padding:10px;"></div>
<!-- 执行绘图函数-->
<script type="text/javascript" charset="UTF-8">
var display = function(time,x,y,z)
{
var echo = echarts.init(document.getElementById("Linechart"));
var option = {
title: {
left: 'left',
text: 'CPU 利用表动态监控',
},
// 调节大小
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
// tooltip 鼠标放上去之后会自动出现坐标
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
backgroundColor: '#6a7985'
}
}
},
legend: {
data: ['1分钟负载', '5分钟负载', '15分钟负载']
},
xAxis: {
type: 'category',
// data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
data: time
},
yAxis: {
type: 'value'
},
series:
[
{
name: "1分钟负载",
stack: "总量",
//data: [10, 25, 99, 87, 54, 66, 2],
data: x,
type: 'line',
areaStyle: {}
},
{
name: "5分钟负载",
stack: "总量",
//data: [89, 57, 85, 44, 25, 4, 54],
data: y,
type: 'line',
areaStyle: {}
},
{
name: "15分钟负载",
stack: "总量",
//data: [1, 43, 2, 12, 5, 4, 7],
data: z,
type: 'line',
areaStyle: {}
}
]
};
echo.setOption(option,true);
}
</script>
<!-- 负责对参数的解析,填充数据 -->
<script type="text/javascript" charset="UTF-8">
var time =["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""];
var cpu_load1 = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
var cpu_load5 = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
var cpu_load15 = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
var update_function = function(recv)
{
time.push(recv.datetime);
cpu_load1.push(parseFloat(recv.load1));
cpu_load5.push(parseFloat(recv.load5));
cpu_load15.push(parseFloat(recv.load15));
if(time.length >=10)
{
time.shift();
cpu_load1.shift();
cpu_load5.shift();
cpu_load15.shift();
console.log("时间数组: " + time);
console.log("1分钟: " + cpu_load1);
console.log("5分钟: " + cpu_load5);
console.log("15分钟: " + cpu_load15);
// 调用绘图函数
display(time,cpu_load1,cpu_load5,cpu_load15);
}
};
</script>
<!-- 负责接收目标主机的CPU负载情况 -->
<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.datetime);
console.log("1分钟: " + recv.load1);
console.log("5分钟: " + recv.load5);
console.log("15分钟: " + recv.load15);
// 调用函数完成数据填充
update_function(recv);
});
});
</script>
</body>
</html>
后台代码使用Flask和Flask-SocketIO搭建了一个实时监控主机CPU负载的WebSocket应用,并将数据通过socketio.emit函数将数据推送给前端展示。
关键点概括如下:
Flask和SocketIO集成:
- 使用Flask框架创建了一个Web应用,并通过Flask-SocketIO集成了WebSocket功能,实现了实时双向通信。
消息接收与实时推送:
- 定义了
socket事件处理函数,用于接收前端通过WebSocket发送的消息。在无限循环中,通过socketio.sleep方法设置每2秒推送一次实时的CPU负载数据给前端。
前端连接和断开事件:
- 定义了
connect和disconnect事件处理函数,分别在WebSocket连接建立和断开时触发。在控制台打印相应信息,用于监控连接状态。
实时数据推送:
- 使用
socketio.emit方法实时将CPU负载数据推送给前端,以更新折线图。推送的数据包括当前时间、1分钟负载、5分钟负载和15分钟负载。
前端页面渲染:
- 通过Flask的
render_template方法渲染了一个HTML页面,用于展示实时更新的CPU负载折线图。
调试信息输出:
- 在每个事件处理函数中使用
print语句输出调试信息,方便监测WebSocket连接和消息的传递过程。
总体来说,该应用实现了一个简单而实用的实时监控系统,通过WebSocket技术实时推送主机CPU负载数据至前端,为用户提供了实时可视化的监控体验。
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(2)
data = time.strftime("%M:%S",time.localtime())
cpu = psutil.cpu_percent(interval=None,percpu=True)
socketio.emit("response",
{"datetime": data, "load1": cpu[0], "load5": cpu[1], "load15": cpu[2]},
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)
运行后,即可输出当前系统下CPU的负载情况,如下图所示;

后端参数拼接
如上所示的代码是在前端进行的数据拼接,如果我们想要在后端进行数据的拼接,则需要对代码进行一定的改进。
前端编写以下代码,通过WebSocket建立通信隧道,而后台则每隔2秒向前台推送传递字典数据。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="https://www.lyshark.com/javascript/jquery/3.5.1/jquery.min.js"></script>
<script type="text/javascript" src="https://www.lyshark.com/javascript/socket.io/socket.io.min.js"></script>
<script type="text/javascript" src="https://www.lyshark.com/javascript/echarts/5.3.0/echarts.min.js"></script>
</head>
<body>
<div id="Linechart" style="height:500px;width:1200px;border:1px solid #673ab7;padding:10px;"></div>
<!-- 执行绘图函数-->
<script type="text/javascript" charset="UTF-8">
var display = function(time,x,y,z)
{
var echo = echarts.init(document.getElementById("Linechart"));
var option = {
title: {
left: 'left',
text: 'CPU 利用表动态监控',
},
// 调节大小
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
// tooltip 鼠标放上去之后会自动出现坐标
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
backgroundColor: '#6a7985'
}
}
},
legend: {
data: ['1分钟负载', '5分钟负载', '15分钟负载']
},
xAxis: {
type: 'category',
// data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
data: time
},
yAxis: {
type: 'value'
},
series:
[
{
name: "1分钟负载",
stack: "总量",
//data: [10, 25, 99, 87, 54, 66, 2],
data: x,
type: 'line',
areaStyle: {}
},
{
name: "5分钟负载",
stack: "总量",
//data: [89, 57, 85, 44, 25, 4, 54],
data: y,
type: 'line',
areaStyle: {}
},
{
name: "15分钟负载",
stack: "总量",
//data: [1, 43, 2, 12, 5, 4, 7],
data: z,
type: 'line',
areaStyle: {}
}
]
};
echo.setOption(option,true);
}
</script>
<!-- 负责接收目标主机的CPU负载情况 -->
<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.datetime);
console.log("1分钟: " + recv.load1);
console.log("5分钟: " + recv.load5);
console.log("15分钟: " + recv.load15);
// 调用绘图函数
display(recv.datetime,recv.load1,recv.load5,recv.load15);
});
});
</script>
</body>
</html>
后台代码则是收集数据,并将数据通过socketio.emit函数,推送给前端。
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)
# 填充数据表
local_time = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""]
cpu_load1 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
cpu_load5 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
cpu_load15 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# 左移填充
def shift(Array, Size, Push):
if len(Array) <= Size and len(Array) >= 0:
Array.pop(0)
Array.append(Push)
return True
return False
# 右移填充
def unshift(Array, Size, Push):
if len(Array) <= Size and len(Array) >= 0:
Array.pop(Size-1)
Array.insert(0,Push)
@app.route("/")
def index():
return render_template("index.html")
# 出现消息后,率先执行此处
@socketio.on("message",namespace="/Socket")
def socket(message):
print("接收到消息:",message['data'])
while True:
socketio.sleep(1)
data = time.strftime("%M:%S",time.localtime())
cpu = psutil.cpu_percent(interval=None,percpu=True)
# 实现数组最大35,每次左移覆盖第一个
shift(local_time,35,data)
shift(cpu_load1,35,cpu[0])
shift(cpu_load5, 35, cpu[1])
shift(cpu_load15, 35, cpu[2])
socketio.emit("response",
{"datetime": local_time, "load1": cpu_load1, "load5": cpu_load5, "load15": cpu_load15},
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)
运行动态图如下所示;

Flask SocketIO 实现动态绘图的更多相关文章
- Flask框架:如何运用Ajax轮询动态绘图
摘要:Ajax是异步JavaScript和XML可用于前后端交互. 本文分享自华为云社区<Flask框架:运用Ajax轮询动态绘图>,作者:LyShark. Ajax是异步JavaScri ...
- Flask框架:运用Ajax轮询动态绘图
Ajax是异步JavaScript和XML可用于前后端交互,在之前<Flask 框架:运用Ajax实现数据交互>简单实现了前后端交互,本章将通过Ajax轮询获取后端的数据,前台使用echa ...
- flask+socketio+echarts3 服务器监控程序(基于后端数据推送)
本文地址:http://www.cnblogs.com/hhh5460/p/7397006.html 说明 以前的那个例子的思路是后端监控数据存入数据库:前端ajax定时查询数据库. 这几天在看web ...
- matplotlib动态绘图
目录 package Process 解决中文乱码问题 simple_plot() scatter_plot() three_dimension_scatter() Jupyter notebook ...
- delphi DLL image 动态绘图 句柄处理
在调用DLL 动态在T Image 绘图时,传入 Image.Canvas.Handle 后,却总是绘不上,有时偶尔能绘上,却没搞清原因,而同样的代码,传入窗体的 Handle ,绘图却正常. 经过 ...
- Flask 重定向到动态url
url_for() 函数是动态构建一个网址给特定的功能是非常有用的.该函数接受函数的名称作为第一个参数,并接受一个或多个关键字参数,每个参数对应于URL的变量部分. 以下脚本演示了使用 url_for ...
- matlab中动态绘图并保存为视频的小例子
如题,多的就不说了,先上一个效果: 每隔0.1秒,绿色的直线转动一个角度. 再看看代码如何实现: fuction main clear; clc; %%%%%%%%%%%%%%%%%%%%%%%%%% ...
- python matplotlib动态绘图
matplotlib animation的官方文档: http://matplotlib.org/api/animation_api.html 接下来完成一个实时获取cpu数值,并绘图的功能. 1.动 ...
- VC实现波形不闪烁动态绘图 .
http://blog.csdn.net/xuyongbeijing2008/article/details/8064284 源代码:http://www.vckbase.com/index.php/ ...
- 测开之路二十七:Flask基础之动态路由
参数化,用<变量名> 也可以指定变量类型 类型不对的时候会报错
随机推荐
- LeetCode 周赛上分之旅 # 36 KMP 字符串匹配殊途同归
️ 本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 和 BaguTree Pro 知识星球提问. 学习数据结构与算法的关键在于掌握问题背后的算法思维框架,你的思考越 ...
- nginx搭建静态文件下载服务器
配置文件大致内容 server { # 监听8001端口 listen 8001; server_name 192.168.0.2; # 指定使用utf8的编码 charset utf-8; # 内容 ...
- 学好Elasticsearch系列-聚合查询
本文已收录至Github,推荐阅读 Java随想录 微信公众号:Java随想录 先看后赞,养成习惯. 点赞收藏,人生辉煌. 目录 概念 doc values 和 fielddata multi-fie ...
- 震惊!CSS 也能实现碰撞检测?
本文,我们将一起学习,使用纯 CSS,实现如下所示的动画效果: 上面的动画效果,非常有意思,核心有两点: 小球随机做 X.Y 方向的直线运动,并且能够实现碰撞到边界的时候,实现反弹效果 小球在碰撞边界 ...
- 《SQL与数据库基础》23. 读写分离
目录 读写分离 一主一从 准备 配置 双主双从 准备 配置 主库配置 从库配置 从库关联主库 主库相互复制 双主双从读写分离 本文以 MySQL 为例.以 MyCat 数据库中间件为例,通过 MyCa ...
- 企业级低代码平台,通用代码生成平台,Java开源项目(附源码)
项目介绍 Jeecg-Boot 是一款基于代码生成器的智能开发平台!采用前后端分离架构:SpringBoot,Mybatis,Shiro,JWT,Vue&Ant Design.强大的代码生成器 ...
- Java实践项目 - 购物车模块
Smiling & Weeping ----世界上美好的东西不太多,立秋傍晚从河对岸吹来的风, 加入购物车 1.数据创建--创建t_cart CREATE TABLE t_cart( cid ...
- Burp Suite Extension Development Guide
Burp Suite是什么? Burp Suite是一款Web应用程序渗透测试工具,可以帮助用户发现和利用Web应用程序中的漏洞,提高渗透测试的效率和精度. Web应用程序最常用的传输数据的协议就是H ...
- Golang日志新选择:slog
go1.21中,slog这一被Go语言团队精心设计的结构化日志包正式落地,本文将带领读者上手slog,体会其与传统log的差异. WHY 在日志处理上,我们从前使用的log包缺乏结构化的输出,导致信息 ...
- ActivityNotFoundException
activity 加入 AndroidManifest android.content.ActivityNotFoundException: Unable to find explicit acti ...