简历项目内容
项目描述:
系统由多台服务器和多个选矿设备(如球磨机、浮选机等)组成,负责处理/监控选矿设备的运行数据。系统架构包括数据库**/**网络通信服务器,以及设备交互的客户端系统。数据库用于存储所有设备的实时运行数据、故障记录和任务状态;网络通信服务器负责从选矿设备客户端接收传感器数据并向设备发送控制指令。每台选矿设备通过网络通信与服务器进行实时交互,接收任务指令并反馈设备运行状态。提供UI界面,展示设备运行的各项数据,包括温度、负载和速度等。
项目功能开发:
a. 网络通信模块:基于C++使用Socket编程,构建自定义TCP协议,实现选矿设备的传感器数据和控制指令传输,设计自定义数据包结构,解决粘包和拆包问题。
b. 数据存储模块:基于MySQL数据库设计并实现数张表,包括设备运行日志表,任务状态表,故障信息表等;集成ORM框架,实现数据库表映射为对象,简化SQL编写;
c. 设备管理模块:采用IOCP模型集成自定义线程池模拟Proactor模式,实现异步对多个设备(球磨机、浮选机等)并发任务调度与执行;支持动态线程个数调整;引入缓冲队列实现生产者-消费者模型,优化任务速率不一致问题;
d. 日志模块:基于双缓冲区实设计,采用多进程架构,实现主线程与日志进程解耦,通过本地套接字Socket实现IPC;
e. UI界面模块:基于Qt框架设计并实现多个自定义控件界面,包括使用QWidget实现设备状态监控面板,显示设备的实时状态信息(如运行、停止、故障等);使用QtCharts实现设备运行数据的可视化,实时显示温度、负载、速度等关键参数变化;通过Qt的信号槽机制实现跨线程同步设备数据,实现界面数据实时更新;
功能优化与重构:
a. 网络通信优化:采用单例模式重新设计Socket管理类,实现全局唯一Socket实例,支持网络连接初始化和管理,简化连接和数据传输逻辑;重构数据包包头,实现嗅碳包过滤;
b. 界面UI优化:采用MVC架构重构客户端UI界面。实现Model层负责获取并更新选矿设备(如球磨机、浮选机)运行数据,View层通过Qt展示设备状态和任务进度,Controller层处理操作员指令如设备启动、停止和任务调度。
c. 数据库访问优化:引入数据库连接池,减少连接创建和销毁开销。
概述
系统组成:多台服务器和多个选矿设备
系统功能:负责处理/监控选矿设备的运行数据
系统架构:数据库和网络通信服务器,与设备交互的客户端系统
具体概述:数据库用于存储所有设备的实时运行数据,故障记录和任务状态,网络通信服务器负责从选矿设备客户端接收传感器数据并向设备发送控制指令。
每台选矿设备通过网络通信向服务器进行实时交互,接收任务指令并反馈设备运行时状态;之后客户端根据服务器信息来展示设备运行的各种数据,包括温度,负载和速度等
总体而言,多个选矿设备向服务器发送数据,数据内容包括各个设备的温度,负载和运行速度等,服务器会使用MySQL数据库来存储各个数据,而客户端是用于UI的展示,从服务端获取各个选矿设备的具体数据,用于图表的展示
功能设计
1.网络通讯
基于C++使用socket编程,并且构建自定义TCP协议包,实现选矿设备的传感器数据和控制指令传输,设计自定义数据包结构,解决粘包和拆包问题
具体描述:使用Windows端的socket的API创建TCP服务端和客户端,服务端用于监听来自各个设备的请求,由于TCP是流式协议,所以数据的传输和接收是没有边界的,那就会造成发送的时候操作系统可能会将几个包一起发送,在接收的时候可能收到不完整的包,包的设计:包头,长度,类型,消息体,校验和
2.数据存储模块
基于MySQL数据库设计并实现多张表,比如设备运行日志表(日志ID,设备ID,时间戳,温度,负载,速度,其他传感器数据),任务状态表(任务ID,任务类型,开始时间,结束时间,当前状态(待执行,执行中,完成,失败)),故障信息表(故障ID,设备ID,故障类型,发生时间,描述,处理状态);集成ORM框架,实现数据库表映射为对象,简化SQL编写;(性能优化:索引)
具体描述:在MySQL数据库中设计了四张表,分别为设备表,设备运行日志表,任务状态表,故障信息表,设备运行日志表,任务状态表,故障信息的主键分别与设备表的主键构成外键关系;使用ODB ORM框架,在使用数据库之前需要先创建对应的C++类,比如设备类,故障类,日志信息类,任务类,使用使用SOCI框架生成对应的MySQL数据表文件user.hxx
,之后使用宏来封装对应的SQL语句操作,来简化代码来增加可读性,对于ODB框架的使用,首先需要与MySQL建立连接后,创建一个会话类,之后就是基于该会话使用对应的宏才进行数据操作(需要使用事务)
3.设备管理模块
采用IOCP模型集成自定义线程池模拟Proactor模式,实现异步对多个设备并发任务调度与执行;支持动态线程个数调整;引入缓冲队列实现生产者-消费者模型,优化任务速率不一致问题
具体描述:首先需要定义任务,任务是对一个std::function<void())
的回调函数的封装,再添加设备ID,采用Windows端异步的网络IO模型来接收事件,之后创建一个生产者消费者模型来生成一个缓冲队列(使用互斥量和信号量机制),用这个队列来存储任务,之后线程池会包含这个生产者消费者队列,用这个队列来接收外面来的任务,之后线程池初始化,根据线程数量来初始化vector<std::thread>
创建一个IOCP管理类,IOCP类中存在线程池变量,初始化IOCP端口和自己的网络套接字后,将自己的网络套接字绑定IOCP端口后,将跨线程监听的任务添加到线程池的任务队列,让线程池负责运转监听任务,当有请求来临时,使用重叠结构提取请求并且构造任务类添加到线程池中,让线程池中的线程来处理
4.日志模块
基于双缓冲区实设计,采用多进程架构,实现主线程与日志进程解耦,通过本地套接字Socket实现IPC
具体描述:日志模块主要是主进程和其他进程产生日志,日志模块负责接收并且写入日志,日志服务器采用本地套接字的方式来接收来自其他进程或线程的数据,具体表现在使用基于线程的静态变量的客户端与日志服务器建立连接,之后发送日志信息给日志模块来写日志;而日志的记录是日志管理器来完成的,日志管理器里面有双缓冲区: LogBuffer log_buffer1;
和 LogBuffer log_buffer12
,并且有一个指向活跃的缓冲区的指针LogBuffer* active_buffer;
,当每次写日志的时候都会切换一个缓冲区来写入该缓冲区的内容
缓冲区的设计需要考虑线程安全,所以需要对vector<std::string>
进行信号量的设置,比如使用conditional_variable
和unique_lock
来保证线程安全
5.UI界面模块
基于Qt框架设计并实现多个自定义控件界面,包括使用QWidget实现设备状态监控面板,显示设备的实时状态信息(如运行、停止、故障等);使用QtCharts实现设备运行数据的可视化,实时显示温度、负载、速度等关键参数变化;通过Qt的信号槽机制实现跨线程同步设备数据,实现界面数据实时更新;
具体描述:在主窗口创建设备状态监控面板和数据可视化控件,创建并启动线程来定期获取数据,连接数据处理线程的信号到设备状态面板和数据可视化控件的槽,以便实时更新界面。当数据处理线程获取新的设备状态和数据时,信号将被发出,界面将自动更新。
6.功能优化与重构
a. 网络通信优化:采用单例模式重新设计Socket管理类,实现全局唯一Socket实例,支持网络连接初始化和管理,简化连接和数据传输逻辑;重构数据包包头,实现嗅碳包过滤;
b. 界面UI优化:采用MVC架构重构客户端UI界面。实现Model层负责获取并更新选矿设备(如球磨机、浮选机)运行数据,View层通过Qt展示设备状态和任务进度,Controller层处理操作员指令如设备启动、停止和任务调度。
c. 数据库访问优化:引入数据库连接池,减少连接创建和销毁开销。
Model 层
Model 层负责获取并更新选矿设备(如球磨机、浮选机)运行数据。这一层的主要职责包括:
- 数据获取: 从设备或传感器中收集实时数据。这可能涉及到与硬件接口的交互(如通过串口、网络接口等)。
- 数据更新: 根据设备的运行状态和操作指令更新数据。例如,如果设备的状态发生变化(如从“运行”变为“停止”),Model 层需要更新相应的数据。
- 数据存储: 可能需要将数据存储在数据库或文件中,以便后续分析和查询。
- 事件通知: 当数据发生变化时,Model 层需要通知 View 层,以便更新用户界面。可以使用信号槽机制(如 Qt 的信号和槽)来实现这一点。
View 层
View 层通过 Qt 展示设备状态和任务进度。其主要职责包括:
- 界面设计: 使用 Qt 的各种控件(如 QLabel、QProgressBar、QTableView 等)来构建用户界面,显示设备的状态信息和任务进度。
- 数据绑定: 将 Model 层的数据与 View 层的控件进行绑定。当 Model 层的数据发生变化时,View 层能够自动更新显示的内容。
- 用户交互: 接收用户的输入(如按钮点击、滑动条调整等),并将这些输入传递给 Controller 层进行处理。
Controller 层
Controller 层处理操作员指令,如设备启动、停止和任务调度。其主要职责包括:
- 用户输入处理: 监听用户的操作(例如,启动或停止设备的按钮),并根据输入执行相应的操作。
- 与 Model 的交互: 根据用户的指令,调用 Model 层的方法来更新设备的状态,例如发送启动或停止命令给设备。
- 更新 View: 在必要时,通知 View 层更新显示的内容(例如,当设备状态改变时更新界面)。