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负载数据给前端。

前端连接和断开事件:

  • 定义了connectdisconnect事件处理函数,分别在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,psutilasync_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,psutilasync_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 Truereturn 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)

运行动态图如下所示;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/206280.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

软件测试面试最全八股文

请你说一说测试用例的边界 参考回答&#xff1a; 边界值分析法就是对输入或输出的边界值进行测试的一种黑盒测试方法。通常边界值分析法是作为对等价类划分法的补充&#xff0c;这种情况下&#xff0c;其测试用例来自等价类的边界。 常见的边界值 1)对16-bit 的整数而言 32…

【日常总结】优雅升级Swagger 2 升至 3.0, 全局设置 content-type application/json

目录 一、场景 二、问题 三、解决方案 四、延伸 上一节&#xff1a;【日常总结】Swagger-ui 导入 showdoc &#xff08;优雅升级Swagger 2 升至 3.0&#xff09;-CSDN博客 一、场景 接上一节&#xff1a;在 Swagger3Config extends WebMvcConfigurationSupport&#xff0c…

Python基础语法之学习字符串快速格式化

Python基础语法之学习字符串快速格式化 一、代码二、效果 一、代码 # 通过f"{占位}"控制字符串快速格式化,不做精度控制 name "张三" age 13 money 12.5 text f"姓名是{name},年龄是{age},钱是{money}" print(text)二、效果 每一天都是一个…

Python入门06布尔值

目录 1 什么是布尔值2 怎么生成布尔值3 在控制程序中使用布尔值4 数据过滤、排序和其他高级操作总结 1 什么是布尔值 首先我们要学习一下布尔值的定义&#xff0c;布尔值是一种数据类型&#xff0c;它只有两个可能的值&#xff1a;True&#xff08;真&#xff09;或 False&…

前端vue3——html2canvas给网站截图生成宣传海报

文章目录 ⭐前言⭐选择html2canvas实现网页截图&#x1f496; 截图 ⭐图片url截图显示不出来问题&#x1f496; 解决 ⭐最终效果&#x1f496; 定义海报 ⭐总结⭐结束 ⭐前言 大家好&#xff0c;我是yma16&#xff0c;本文分享关于 前端vue3——html2canvas给网站截图生成宣传…

2.19 keil里面工具EventCorder使用方法

设置方法如下&#xff1a; 添加初始化代码如下&#xff1a; eventRecord.c #include "eventRecord.h" #include "usart.h" extern UART_HandleTypeDef *pcControlUart;/* RecordEvent初始化 */ void InitEventRecorder(void) {#ifdef RTE_Compiler_Even…

MySQL 批量插入记录报 Error 1390 (HY000)

文章目录 1.背景2.问题3.分批插入4.一次最多能插入多少条记录&#xff1f;5.什么是 Prepared Statement&#xff1f;参考文献 1.背景 Golang 后台服务使用 GORM 实现与 MySQL 的交互&#xff0c;在实现一个通过 Excel 导入数据的接口时&#xff0c;使用 Save 方法一次性插入全…

用Java制作简易版的王者荣耀

第一步是创建项目 项目名自拟 第二部创建个包名 来规范class 创建类 GameFrame 运行类 package com.sxt;import java.awt.Graphics; import java.awt.Image; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import j…

ESP32 ESP-IDF5.1 在Visual Studio Code中自定义分区表与调整Flash大小

好记心不如烂笔头 使用ESP-IDF开发ESP32的时候,要是同时用到蓝牙和WIFI的话,很多时候会提示Flash不够, 我是照着这样解决的,存档记录 来源 : zaixingxing2539 大佬的 ESP32 ESP-IDF5.0 在VSCODE中自定义分区表 用Visual Studio Code自定义分区表 # ESP-IDF Partition Table…

【MySQL:从零开始练级】环境安装与基础认识

hello大家好&#xff0c;失踪人口回归&#xff0c;今天开始新专栏MySQL&#xff1a;从零开始练级,今天给大家分享MySQL的环境安装与基础认识&#xff0c;希望大家能有所学习收获。 目录 1️⃣ Centos 7环境下安装 2️⃣什么是数据库 3️⃣服务器、数据库、表关系 4️⃣MySQ…

批量将本地N个英文Html文档进行中文翻译-操作篇

Unity3D特效百例案例项目实战源码Android-Unity实战问题汇总游戏脚本-辅助自动化Android控件全解手册再战Android系列Scratch编程案例软考全系列Unity3D学习专栏蓝桥系列ChatGPT和AIGC &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分…

AtCoder Beginner Contest 330 A~F

A.Counting Passes(暴力) 题意&#xff1a; 给定 n n n个学生的分数&#xff0c;以及及格分 x x x &#xff0c;问多少人及格了。 分析&#xff1a; 暴力枚举&#xff0c;依次判断每个学生的分数即可。 代码&#xff1a; #include <bits/stdc.h> using namespace s…

Kotlin学习——kt里的集合List,Set,Map List集合的各种方法之Int篇

Kotlin 是一门现代但已成熟的编程语言&#xff0c;旨在让开发人员更幸福快乐。 它简洁、安全、可与 Java 及其他语言互操作&#xff0c;并提供了多种方式在多个平台间复用代码&#xff0c;以实现高效编程。 https://play.kotlinlang.org/byExample/01_introduction/02_Functio…

Django之ORM

ORM全称对象关系映射 作用&#xff1a;通过python面向对象的代码简单快捷的操作数据库&#xff0c;但是封装程度太高&#xff0c;有时候sql语句的效率偏低&#xff0c;需要自己写sql语句 类----->表 对象--->记录 对象属性--->记录某个字段对应的值 写在models.p…

Webhook端口中的自签名身份验证

概述 有时&#xff0c;可能需要通过 Webhook 端口从交易伙伴处接收数据&#xff0c;但该交易伙伴可能需要更多的安全性&#xff0c;而不仅仅是用于验证入站 Webhook 请求的基本身份验证用户名/密码 – 或者您可能只想在入站 Webhook 消息上添加额外的安全层。 使用 Webhook 端…

LeetCode(44)存在重复元素 II【哈希表】【简单】

目录 1.题目2.答案3.提交结果截图 链接&#xff1a; 存在重复元素 II 1.题目 给你一个整数数组 nums 和一个整数 k &#xff0c;判断数组中是否存在两个 不同的索引 i 和 j &#xff0c;满足 nums[i] nums[j] 且 abs(i - j) < k 。如果存在&#xff0c;返回 true &#xf…

Maven 简单配置阿里云镜像

配置步骤&#xff1a; 1、找到 maven 的安装目录&#xff0c;修改settings.xml 2、在文件中找到<mirrors>标签&#xff0c;然后再标签中添加阿里云配置即可 <mirror><id>aliyunmaven</id><mirrorOf>*</mirrorOf><name>阿里云公共…

C# Onnx 百度飞桨开源PP-YOLOE-Plus目标检测

目录 效果 模型信息 项目 代码 下载 C# Onnx 百度飞桨开源PP-YOLOE-Plus目标检测 效果 模型信息 Inputs ------------------------- name&#xff1a;image tensor&#xff1a;Float[1, 3, 640, 640] name&#xff1a;scale_factor tensor&#xff1a;Float[1, 2] ----…

Flash学习

FLASH介绍 FLASH是常用的&#xff0c;用于存储数据的半导体器件&#xff0c;它具有容量大&#xff0c;可重复擦写&#xff0c;按“扇区/块”擦除、掉电后数据可继续保存的特性。 常见的FLASH有NOR FLASH和NAND FLASH。 NOR和NAND是两种数字门电路&#xff0c;可以简单地认为F…

进程间通信基础知识【Linux】——上篇

目录 一&#xff0c;理解进程之间的通信 1. 进程间通信目的 2. 进程间通信的技术背景 3&#xff0c;常见的进程间通信 二&#xff0c;管道 1. 尝试建立一个管道 管道的特点&#xff1a; 管道提供的访问控制&#xff1a; 2. 扩展&#xff1a;进程池 阶段一&#xff1a…