从word文档粘贴过来的,没做太多排版,以后会来重新排版的。
机房管控系统_服务器端详细设计
目 录
5. 应用程序结构与多线程.................................................................................... 13
a) 每个IO操作的数据Struct PER_IO_OPERATION_DATA.................................... 14
b) 机房实时状态数据Struct 机房_STATE_DATA................................................... 14
c) 机房信息 Struct 机房_Info........................................................................... 15
e) 放电信息 structOUT_ELETRIC_M.................................................................... 16
七. 技术点............................................................................................................ 16
《机房管控系统需求手册》
《机房管控系统_概要设计》
《数据库设计》
《机房管控系统_通信协议》
系统详细设计,提供编码依据。
机房管控系统服务器端程序,主要作用为接收监控设备采集的数据,保存至数据库,对采集的数据做简单分析,做进一步处理。短信报警。
设备采集的数据包括:机房运行过程中的输入电压、输出电压、市电电压、输入电流、输出电流、机房状态、空调温度、空调状态。过载状态。
服务器端程序可以根据数据分析结果,向监控设备发送控制指令,可以短息报警等等。
对于目前的机房管控系统,服务器主动向设备获取数据。
网络模块:处理网络相关请求和发送。端口监听,socket处理。
数据解析:对网络接收到的数据包,解析成本相关类模型。
数据分析:机房LOG状态数据分析,提供分析结果。
数据处理:机房LOG数据处理,存储报警等。
数据库读写:数据库相关操作。
用例说明:
1.状态信息:监控设备将状态数据实时上报给服务器端,服务接受并处理
2.分析:服务器对相应设备的数据做分析处理。
3.存储:服务器将设备数据储存到数据库中。
4.获取与交互:客户端获取设备信息数据等信息,和设备交互控制等。
综述:
服务器封装类:提供IOCP服务器,工作者线程,得到一个机房LOG 信息,得到其他信息,设备交互控制,这几个服务。
设备数据:机房设备在数据库中基本信息,抽象为本模型
Device:将对机房管控设备抽象为本类模型。
设备集:提供对多个设备的统一操作,包括设备集的初始化,查找一个设备,更新设备集。
Base:其他类继承本类,构造函数,初始化Type类型。
服务器封转类(Server):封装IOCP模型和Socket通信,获取设备信息,客户端请求,其他信息。
属性 |
类型 |
说明 |
strIP |
Socket |
基本socket |
port |
int |
本地监听端口 |
Ip |
int |
本地ip |
Split |
Split(数据解析类) |
解析网络数据包 |
DeviceList |
DeviceList * (设备集) |
设备集的引用 |
SendData(CHAR * BUFF,int ip,int port);//通过网络发信息 | ||
Static winApi IOCPListen(int ip,int port); //静态方法,线程的执行体。 | ||
Static void WorkerThread();//IOCP的工作者线程 | ||
GetLog(CHAR*BUFF);//处理一条机房LOG信息 | ||
GetOther(CHAR * BUFF,type);//处理其他请求,type表示请求类型。(交给设备或给主线程发消息) |
说明: 访问数据集时,要做线程同步。用临界区,锁住全局Map对象。
接口:
设备集类(DeviceList):多个设备储存集合
属性 |
类型 |
说明 |
MapDevice |
Map<Device> |
用map储存的设备集合,提高查找效率 |
findDevice(string id);//查找设备 | ||
InitDeviceList();//初始化设备集列表 | ||
UpdataDeviceList();//更新设备集的设备内容。 |
说明:
参考:
物理设备类(Device):
属性 |
类型 |
说明 |
CHAR ID;LPPER_IO_OPERATION_DATA per_io_opera_data; |
//用于IO模型 |
机房Info; |
机房_Info |
//机房信息 |
OutEletric; |
OUT_ELETRIC_M |
//放电信息 |
state_data; |
机房_STATE_DATA[10] |
//状态数据,用数组保存最近10次数据。用于业务分析 |
MessageInfo |
MessageStruct[10] |
//最近十次短信信息 |
iStateLength | Int |
//状态数据数组已使用长度 |
iMessageLength |
Int |
//短信数组已使用长度 |
//断市电 | ||
//恢复市电 | ||
//设置阀值 | ||
//读状态数据(机房LOG) | ||
//业务分析(业务分析里面有报警) | ||
//状态帧分析 | ||
//其他帧处理 | ||
//心跳帧处理 |
说明:将对机房管控设备抽象为本类模型。参考:基类(Base):
属性 |
类型 |
说明 |
Type |
Enum |
所有类的基类 |
说明:其他类继承本类,构造函数,初始化Type类型。
Enum ObjEnum{Base=1,DeviceData=2,Device=3,ProteclBase=4,Protecl=5,Model=6,Dal=7,警报=8,短信猫=9}
配置文件(IniConf):
属性 |
类型 |
说明 |
Type |
Enum |
所有类的基类 |
IP |
string | 地址 |
Username |
String |
账号 |
Password |
String |
密码 |
com |
String |
SMS的COM口 |
TimeOutConn |
Int |
连接超时 |
TimeOutSend |
Int |
发送超时 |
TimeOutRecv |
In |
接收超时 |
LoadIni();//装载INI | ||
SaveIni();//保存INI |
说明:其他类继承本类,构造函数,初始化Type类型。
EnumObjEnum{Base=1,DeviceData=2,Device=3,ProteclBase=4,Protecl=5,Model=6,Dal=7,警报=8,短信猫=9}
配置文件格式:
[SQL SERVER]
IP=.
username=sa
password=wangbing
[Serial Ports]
Port=COM3
[Time Out]
TimeOutConn=10000
TimeOutSend=10000
TimeOutRecv=10000
数据解析类(SplitData):
属性 |
类型 |
说明 |
UCHAR * BUFF |
UCHAR * |
字节流 |
Split();//解析处理,返回一个机房状态结构 |
说明:
参考
业务处理类(AnayleData):
属性 |
类型 |
说明 |
机房_data |
Device * |
引用Device |
Anayle();//分析处理一个Device |
说明:
参考
报警业务处理类(AlarmMake):
属性 |
类型 |
说明 |
机房_Data |
Device * |
引用Device |
Aararm();//分析一个Device, |
短信猫(SMSModel):
属性 |
类型 |
说明 |
|
SendMessage();//发送一条短信 |
数据库访问(DBAccess):
属性和方法 |
类型 |
说明 |
Init(); |
//初始化 |
ExecueSql(); |
//执行sql |
GetDataSet(); |
//得到ds |
说明:数据库的基本操作抽象到这里。
参考
机房信息表(机房Make):
属性和方法 |
类型 |
说明 |
ReadAllDeviceData(vector <机房_INFO> * pVec); |
//读所有,返回机房_INFO的列表。 |
Bool UpDateDevice(机房Info); |
参数:struct机房info |
//更新值 |
bool UpDateDevice(机房_STATE_DATA & 机房StateData); //更新一个机房状态信息 |
说明:数据库机房表操作
参考
日志表(LogMake):
属性 |
类型 |
说明 |
AddJounral; |
//加一条日志 |
AddOutputDetail (); |
//加明细 |
说明:数据库日志表操作
参考
放电记录表类(OutputMake):
属性 |
类型 |
说明 |
AddOutputInfo(); |
//加放电主信息 |
AddOutputDetail (); |
//加放电明细 |
说明:数据库放电记录表和放电明细表的操作
参考
空调状态变化表(AC_Make):
属性 |
类型 |
说明 |
addACChangeInfo(); |
//空调变化 |
说明:数据库空调状态变化表操作
参考
主线程的消息:
1. 定时器,处理内容:心跳帧检查,某一个设备十五秒没有心跳帧,认为离线。
2. 五分钟时,读数据库,比较是否有新设备,是否有设备数据需要更新,有的话,锁全局变量,更新设备信息。
3. 自定义消息1:IOCP 工作者线程发给主线程,更新主线程的缓存数据的消息,主线程也认为是心跳贞
4. 自定义消息2:单机客户端的请求交给主线程处理.单机客户端请求不能太多否则,消息处理不过来.定时器优先级底,可能丢失消息.
5. 各种需要锁全局设备缓存的请求操作等,用主线程处理,通过线程间消息通信.
#define WM_UPDATA_机房_STATE WM_USER+101
#define WM_CLIENT_机房_STATE WM_USER+102
伪代码
DeviceList
各个线程有自己的缓存,主线程定时判断是否需要更新,当需要更新时,主线程更新全局缓存,各个线程判断后用全局缓存更新各自的缓存。
a) 功能描述:处理网络相关请求和发送。端口监听,socket处理。
目前版本提供两种获取数据方式,服务器主动获取和监控设备主动上报。
1.主动获取方式,服务器开线程主动轮循所有设备,获得机房LOG后加入IP端然后转发给本地IOCP处理。IOCP工作者线程解析时,根据机房LOG后面的IP端,判断出是哪个设备的状态信息。
2.IOCP监听方式,根据socket获取IP和报文端中获取IP,根据这个IP判断出是哪个设备的机房LOG信息。
3.设备离线判断,主动获取时,如果连续多次(次数待定)没获取成功,则认为设备离线,更新设备状态为离线。IOCP方式,主线程开15秒定时器,扫描主线程缓存中设备状态最后更新时间,大于N秒(待定)的认为离线(秒数视设备上报周期而定)。
b) 接口:
服务器类的几个接口。
a) 功能描述:对网络接收到的数据包,解析成相关类模型。
1.机房LOG帧:解析为一个机房_STATE_DATA结构。
2.时间同步帧:判断为时间同步帧,立即回发时间。
3.信息请求帧:(目前没有)。
4.请求设备信息列表:客户端操作,返回设备集对象的序列化,客户端按照设备集对象解析内存空间。
5.请求所有设备状态数据:客户端操作,返回设备对象的序列化,客户端按照设备集对象解析内存空间。
b) 接口:
a) 功能描述:机房LOG状态数据分析,提供分析结果。
业务分析包括,放电分析,市电异常
放电时,需要保存每次收到的状态值.
1.判断短路状态。
b) 接口:
a) 功能描述:机房LOG数据处理,存储报警等。
1. 保存数据状态量。
2. 短信报警。
b) 接口:
a) 功能描述:数据库相关操作。
b) 接口:
1. 执行一条sql
2. 返回一个dataSet
3. 更新一个机房状态信息
4. 返回所有机房的dataSet
5. 插入一条放电记录
6. 插入放电记录明晰。
a) 主线程的几个定时器。离线判断,预约放电,更新缓存。
b) 选项:使用状态分析(对接收到的状态值作分析),不使用状态分析(接收到的状态值不分析)。
1. 返回所有设备信息列表。
2. 读取指定设备信息。
a) 每个IO操作的数据Struct PER_IO_OPERATION_DATA
typedef struct//每个IO操作的数据
{
OVERLAPPED Overlapped;
WSABUF DataBuf;
CHAR Buffer[DATA_BUFSIZE];
DWORD bytesRECV;
SOCKET Socket;
DWORD OpType;
} PER_IO_OPERATION_DATA, *LPPER_IO_OPERATION_DATA;
b) 机房实时状态数据Struct 机房_STATE_DATA
typedef struct //机房实时状态电压等信息
{
CHAR battery_voltage_str [VOLTAGE_LEN + 1]; // 电池电压 接收的值
CHAR battery_voltage[VOLTAGE_LEN + 1]; // 电池电压
CHAR input_voltage_str [VOLTAGE_LEN + 1]; // 市电输入电压 接收的值
CHAR input_voltage[VOLTAGE_LEN + 1]; // 市电输入电压
CHARcurrent_str [VOLTAGE_LEN+1]; //电流 接收的值
CHARcurrent[VOLTAGE_LEN+1]; //电流
CHARinput_Eletric_str [VOLTAGE_LEN+1]; //输入电流 接收的值
CHARinput_Eletric[VOLTAGE_LEN+1]; //输入电流
CHARoutput_Eletric_str [VOLTAGE_LEN+1]; //输出电流 接收的值
CHARoutput_Eletric[VOLTAGE_LEN+1]; //输出电流
CHAR output_voltage_str [VOLTAGE_LEN + 1]; // 机房输出电压 接收的值
CHAR output_voltage[VOLTAGE_LEN + 1]; // 机房输出电压
CHAR AC_Temperature_str[VOLTAGE_LEN + 1]; // 空调温度 接收的值
CHAR AC_Temperature[VOLTAGE_LEN + 1]; // 空调温度
CHAR AC_State_str [VOLTAGE_LEN + 1]; // 空调状态 接收的值
CHAR AC_State [VOLTAGE_LEN + 1]; // 空调状态
CHARstate[STATE_LEN + 2];
CHARstate[STATE_LEN + 2];
CHAR datetime[DATETIME_LEN + 1]; // 状态截获时间
CHARip[IP_BUFSIZE]; //传递过来的ip
CHAROverLoad_state[STATE_LEN +2]; //负载状态(根据输出电流判断)
}机房_STATE_DATA, * LP机房_STATE_DATA;
c) 机房信息 Struct 机房_Info
typedef struct///机房信息
{
double iParam_Input; //电压校正参数输入
double iParam_Output; //电压校正参数输出
double iParam_Battery; //电压校正参数电池
CHARLow_Volage[VOLTAGE_LEN+1]; //电池最低采样电压值
CHARLow_Output_Eletric[VOLTAGE_LEN+1]; //过载电流(采样值)
CHARCycleDate[50]; //预约时间的起点
CHARphone[MAX_PHONE]; //负责人电话
CHARMessageText[50]; //报警短信内容
CHAREquimentName[30]; //设备名称
CHARIsCycleCountNum[2]; //是否阀值恢复 f阀值恢复 t到时间恢复
int CycleNum; //预约周期
int CycleCountNum; //放电时的允许时间
}机房_Info;
/* 短信基本内容*/
typedef struct {
char Addr[32]; //服务中心号码,服务中心号码是短消息的必有属性,系统通过at指令获得并赋值 //编辑短信时看不到,新的手机卡一般买到手都是设置好的,
char Phone[32]; //对方号码
char Message[200]; //短信内容
int iAddr; //串长
int iPhone; //串长
int iMessage; //串长
} MessageStruct;
e) 放电信息 struct OUT_ELETRIC_M
typedef struct//放电信息,当机房放电时,生成一个guid,并记录时间
{
CHARid[DATETIME_LEN + 1 + IP_BUFSIZE + 1]; //放电记录id,放电时间+ ip
CHARstate; //放电状态,Y放电记录,N没有放电记录
CHARWarnTime[20]; //放电开始时间
}OUT_ELETRIC_M;
1. IOCP介绍
异步完成端口,IOCP主线程,打开多个工作者线程,处理业务工作。IOCP监听端口,当有读写时,自动将该socket交给某一个工作者线程,监听立即返回。处理工作由工作者线程处理。
IOCP主线程:
IOCP工作者线程:LPOVERLAPPED结构详解:GetQueuedCompletionStatus函数说明:
2. 线程锁
临界区概念:全局有多个变量时,对有多个线程访问的变量,每一个使用该变量的线程,都要做进入临界区,退出临界区的操作。当访问只有线程自己使用的全局变量时,不需要做进入临界区退出临界区的操作。
3. Windows消息循环
SendMessage与PostMessage的区别。程序中根据情况灵活选择。