#include "stdafx.h" #include "AlarmFSM.h" #include "Event.h" #include "CommEntityRestful.hpp" #include "json/json.h" namespace Task { //发送告警 struct SendAlarmTask : public ITaskSp{ AlarmFSM* m_fsm; explicit SendAlarmTask(AlarmFSM* f) : m_fsm(f) {} void Process(){ LOG_FUNCTION(); //改为循环处理告警 int logSum=0; while(true){ if(m_fsm->m_NewUploading_alarm.empty()&&m_fsm->m_unSendAlarm.IsNullOrEmpty()){ if(logSum>=120){ DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM)("no warn,wait 6min"); logSum=0; }else{ logSum++; } Sleep(3000);//无重发和新的告警则等待 continue; } logSum=0; #ifdef RVC_OS_WIN IHttpFunc* client; client = create_http(m_fsm->HttpsLogCallBack); bool isSendSucc=false;//查询是否成功标志 if(SendAlarmTaskImpl(client)){ isSendSucc = true; }else{ isSendSucc = false; } client->Destory(); #else bool isSendSucc=false;//查询是否成功标志 if(SendAlarmTaskImpl()){ isSendSucc = true; }else{ isSendSucc = false; } #endif //m_fsm->PostEventFIFO(new SendAlarmEvent(isSendSucc));//返回处理结果 if(isSendSucc){ //成功 DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM)("send alarm statistic m_iRec=%d , m_iThrow=%d , UnSend=%d , m_iSucc=%d , m_iFail=%d",m_fsm->m_iRec,m_fsm->m_iThrow,m_fsm->m_NewUploading_alarm.size(),m_fsm->m_iSucc,m_fsm->m_iFail); if(!m_fsm->m_NewUploading_alarm.empty()){ Sleep(2000);//赶紧发送 continue; }else{ Sleep(3000);//等待 continue; } }else{ //失败,超过未发送成功的告警时间间隔,丢弃告警信息 CSmallDateTime endTime = CSmallDateTime::GetNow(); if(((DWORD)endTime-(DWORD)m_fsm->m_sendBeginTime)>m_fsm->m_maxResendTime){ m_fsm->m_unSendAlarm="";//置为空 m_fsm->m_iFail = m_fsm->m_iFail+ m_fsm->m_eachSum ;//发送失败 LogWarn(Severity_Low,Error_Exception,WARN_ALARM_SEND_FAIL,CSimpleStringA::Format("throw away alarm num= %d,m_iFail=%d,m_iThrow=%d",m_fsm->m_eachSum,m_fsm->m_iFail,m_fsm->m_iThrow)); m_fsm->m_eachSum =0;//清空批次数量 m_fsm->m_sendBeginTime = CSmallDateTime::GetNow(); DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM)("send alarm statistic m_iRec=%d , m_iThrow=%d , UnSend=%d , m_iSucc=%d , m_iFail=%d",m_fsm->m_iRec,m_fsm->m_iThrow,m_fsm->m_NewUploading_alarm.size(),m_fsm->m_iSucc,m_fsm->m_iFail); } Sleep(20*1000);//失败重发等待 continue; } } } #ifdef RVC_OS_WIN bool SendAlarmTaskImpl(IHttpFunc* client){ HttpStruct::SendAlarmTaskReq qTempReq; HttpStruct::SendAlarmTaskRet qTempRet; if(m_fsm->m_unSendAlarm.IsNullOrEmpty()){ //组装新的json告警信息 string strJson = m_fsm->alarmJson(); if(strJson.empty()){ return true; }else{ qTempReq.m_reqStr = strJson.c_str();//请求参数 m_fsm->m_unSendAlarm = strJson.c_str(); m_fsm->m_sendBeginTime = CSmallDateTime::GetNow(); } }else{ //重发新的告警信息 qTempReq.m_reqStr = m_fsm->m_unSendAlarm.GetData();//请求参数 DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM)("alarm retry send"); } qTempReq.m_url=m_fsm->m_sendUrl.GetData();//访问地址 //DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM)("alarm send =%s",qTempReq.m_reqStr.c_str()); if(!client->Post(qTempReq, qTempRet)){ DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM).setAPI("SendAlarmTaskImpl")("SendAlarmTask http req fail,url=%s",qTempReq.m_url.c_str()); return false;//失败 } Json::Reader reader; Json::Value rootRet; if (!reader.parse(qTempRet.m_retStr, rootRet, false)) { DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM).setAPI("SendAlarmTaskImpl")("SendAlarmTask parse resp is fail"); return false;//失败 } bool isSucc = rootRet["success"].asBool(); if(isSucc){ DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM).setAPI("SendAlarmTaskImpl")("SendAlarmTask [success] is succ,m_eachSum=%d",m_fsm->m_eachSum); m_fsm->m_unSendAlarm="";//置为空 m_fsm->m_iSucc = m_fsm->m_iSucc+ m_fsm->m_eachSum ;//发送成功 m_fsm->m_eachSum = 0;//清空批次数量 return true;//写入成功 }else{ CSimpleStringA errCode = rootRet["code"].asString().c_str(); if(!errCode.IsNullOrEmpty()||errCode == "10101"){ //DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM).setAPI("SendAlarmTaskImpl")("SendAlarmTask [success] is false,code = 10101"); m_fsm->m_unSendAlarm="";//置为空 m_fsm->m_iFail = m_fsm->m_iFail+ m_fsm->m_eachSum ;//发送失败 LogWarn(Severity_Low,Error_Exception,WARN_ALARM_PARSE_FAIL,CSimpleStringA::Format("SendAlarmTask [success] is false,code = 10101,throw away alarm num= %d,m_iFail=%d",m_fsm->m_eachSum,m_fsm->m_iFail)); m_fsm->m_eachSum = 0;//清空批次数量 return true;//中文乱码解析失败,默认成功 }else{ DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM).setAPI("SendAlarmTaskImpl")("SendAlarmTask [success] is false,code =%s",errCode); return false;//写入失败 } } } #else bool SendAlarmTaskImpl() { HttpClientResponseResult result; HttpClientRequestConfig config(HttpRequestMethod::POST, m_fsm->m_sendUrl.GetData()); string reqStr = ""; if(m_fsm->m_unSendAlarm.IsNullOrEmpty()){ //组装新的json告警信息 string strJson = m_fsm->alarmJson(); if(strJson.empty()){ return true; }else{ reqStr = strJson.c_str();//请求参数 m_fsm->m_unSendAlarm = strJson.c_str(); m_fsm->m_sendBeginTime = CSmallDateTime::GetNow(); } }else{ //重发新的告警信息 reqStr = m_fsm->m_unSendAlarm.GetData();//请求参数 DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM)("alarm retry send"); } config.SetJsonBody(reqStr); RestfulClient client = RestfulClient::getInstance(); config.PreDo(); client.Do(&config, &result); //判断结果 if(result.ResponseOK()){ //解析返回字符串 Json::Reader reader; Json::Value rootRet; if (!reader.parse(result.content, rootRet, false)) { DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM).setAPI("SendAlarmTaskImpl")("SendAlarmTask parse resp is fail"); return false;//失败 } bool isSucc = rootRet["success"].asBool(); if(isSucc){ DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM).setAPI("SendAlarmTaskImpl")("SendAlarmTask [success] is succ,m_eachSum=%d",m_fsm->m_eachSum); m_fsm->m_unSendAlarm="";//置为空 m_fsm->m_iSucc = m_fsm->m_iSucc+ m_fsm->m_eachSum ;//发送成功 m_fsm->m_eachSum = 0;//清空批次数量 return true;//写入成功 }else{ CSimpleStringA errCode = rootRet["code"].asString().c_str(); if(!errCode.IsNullOrEmpty()||errCode == "10101"){ //DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM).setAPI("SendAlarmTaskImpl")("SendAlarmTask [success] is false,code = 10101"); m_fsm->m_unSendAlarm="";//置为空 m_fsm->m_iFail = m_fsm->m_iFail+ m_fsm->m_eachSum ;//发送失败 LogWarn(Severity_Low,Error_Exception,WARN_ALARM_PARSE_FAIL,CSimpleStringA::Format("SendAlarmTask [success] is false,code = 10101,throw away alarm num= %d,m_iFail=%d",m_fsm->m_eachSum,m_fsm->m_iFail)); m_fsm->m_eachSum = 0;//清空批次数量 return true;//中文乱码解析失败,默认成功 }else{ DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM).setAPI("SendAlarmTaskImpl")("SendAlarmTask [success] is false,code =%s",errCode); return false;//写入失败 } } } else { std::string errDetail(result.WhatError()); DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM).setAPI("SendAlarmTaskImpl")("SendAlarmTask http req fail,error=[%s],url=%s", errDetail.c_str(), m_fsm->m_sendUrl.GetData()); return false;//失败 } return true; } #endif }; } AlarmFSM::AlarmFSM() : m_pConnection(NULL),m_b_alarmstate(FALSE) { InitializeCriticalSection(&cs); INIT_LIST_HEAD(&m_uploading_alarm); INIT_LIST_HEAD(&m_uploaded_alarm); m_iEachSend=0;//每次连接发送的数量 m_iRec=0;//累计收到的告警数目 m_iSend=0;//累计队列发送总数 m_iThrow=0;//累计队列丢弃总数 m_iFail=0;//累计发送失败总次数 m_iSucc=0;//累计发送成功总次数 m_CenterModel=0; m_maxResendTime=60; m_eachSum=0; m_initAlarm=false; } AlarmFSM::~AlarmFSM() { DeleteCriticalSection(&cs); } void AlarmFSM::OnStateTrans( int iSrcState, int iDstState ) { //Dbg("trans from %s to %s", GetStateName(iSrcState), GetStateName(iDstState)); DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM)("trans from %s to %s", GetStateName(iSrcState), GetStateName(iDstState)); } void AlarmFSM::OnSysVarEvent( const char *pszKey, const char *pszValue,const char *pszOldValue,const char *pszEntityName ) { } ErrorCodeEnum AlarmFSM::OnInit() { AddStateHooker(this); //...... CSmartPointer spFunction = m_pEntity->GetFunction(); CSmartPointer spConfig; ErrorCodeEnum Error = spFunction->OpenConfig(Config_CenterSetting, spConfig); if (Error_Succeed == Error) { Error = spConfig->ReadConfigValueInt("Alarm", "DealWarningTime", m_nDealWarningTime); if (Error_Succeed == Error) { //Dbg("get DealWarningTime=%d from CenterSetting.ini", m_nDealWarningTime); DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM).setAPI("OnInit")("get DealWarningTime=%d from CenterSetting.ini", m_nDealWarningTime); } else { //Dbg("get DealWarningTime from CenterSetting.ini failed"); DbgWithLink(LOG_LEVEL_WARN,LOG_TYPE_SYSTEM).setAPI("OnInit")("get DealWarningTime from CenterSetting.ini failed"); } int iCenterModel =0; Error = spConfig->ReadConfigValueInt("Alarm", "CenterModel", iCenterModel); if(Error==Error_Succeed){ m_CenterModel = iCenterModel; DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM).setAPI("OnInit")("init read CenterSetting.ini CenterModel=%d",m_CenterModel); }else{ DbgWithLink(LOG_LEVEL_WARN,LOG_TYPE_SYSTEM).setAPI("OnInit")("init read CenterSetting.ini CenterModel failed"); } Error = spConfig->ReadConfigValueInt("Alarm", "maxResendTime", m_maxResendTime); if(Error==Error_Succeed){ DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM).setAPI("OnInit")("init read CenterSetting.ini maxResendTime=%d",m_maxResendTime); }else{ DbgWithLink(LOG_LEVEL_WARN,LOG_TYPE_SYSTEM).setAPI("OnInit")("init read CenterSetting.ini maxResendTime failed"); } CSimpleStringA str=""; Error = spConfig->ReadConfigValue("Alarm", "topic", str); if(Error==Error_Succeed){ m_topic = str; DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM).setAPI("OnInit")("init read CenterSetting.ini topic=%s",str.GetData()); }else{ DbgWithLink(LOG_LEVEL_WARN,LOG_TYPE_SYSTEM).setAPI("OnInit")("init read CenterSetting.ini topic failed"); } Error = spConfig->ReadConfigValue("Alarm", "sendUrl", str); if(Error==Error_Succeed){ m_sendUrl = str; DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM).setAPI("OnInit")("init read CenterSetting.ini sendUrl=%s",str.GetData()); }else{ DbgWithLink(LOG_LEVEL_WARN,LOG_TYPE_SYSTEM).setAPI("OnInit")("init read CenterSetting.ini sendUrl failed"); } Error = spConfig->ReadConfigValue("Alarm", "branchNo", str); if(Error==Error_Succeed){ m_branchNo = str; DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM).setAPI("OnInit")("init read CenterSetting.ini branchNo=%s",str.GetData()); }else{ DbgWithLink(LOG_LEVEL_WARN,LOG_TYPE_SYSTEM).setAPI("OnInit")("init read CenterSetting.ini branchNo failed"); } } else { DbgWithLink(LOG_LEVEL_WARN,LOG_TYPE_SYSTEM).setAPI("OnInit")("open CenterSetting.ini failed"); } if (m_nDealWarningTime == 0) { m_nDealWarningTime = 10; } if(m_maxResendTime <= 0){ m_maxResendTime ==60; } if(m_branchNo.IsNullOrEmpty()){ m_branchNo = "000";//默认是000总行分行号 } return Error_Succeed; } ErrorCodeEnum AlarmFSM::OnExit() { return Error_Succeed; } void AlarmFSM::s0_on_entry() { if(!m_initAlarm){ m_initAlarm=true; //添加集中配置参数读取和判断走分行还是总行 if(m_CenterModel==0){ LogWarn(Severity_Low,Error_Exception,WARN_ALARM_START_OLD_MODE,CSimpleStringA::Format("init alarm old model,model=%d",m_CenterModel)); }else{ LogWarn(Severity_Low,Error_Exception,WARN_ALARM_START_NEW_MODE,CSimpleStringA::Format("init alarm new model,model=%d",m_CenterModel)); } } if(m_CenterModel==0){ //旧模式 //改造为先判断是否不为空,再创建连接,减少空连接数 if(m_NewUploading_alarm.empty()){ //Dbg("no warn,wait 3s"); //DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM)("no warn,wait 3s"); ScheduleTimer(1, 3000);// try 3 seconds later }else{ if (!m_pConnection) { m_pConnection = new AlarmConnection(m_pEntity, this); if (m_pConnection->ConnectFromCentralSetting()&& m_pConnection->IsConnectionOK()) { //创建成功 }else{ //创建失败 //Dbg("connect server fail,config or Servers Error!"); DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM)("connect server fail,config or Servers Error!"); closeClientConn();//断开连接 } } if (!m_pConnection) { ScheduleTimer(1, 10000); // try 10 seconds later } else { PostEventLIFO(new FSMEvent(USER_EVT_JMP_ALARMUP));//跳转S1状态 } } }else{ //新模式 PostEventLIFO(new FSMEvent(USER_EVT_JMP_NEW_ALARM));//跳转新模式发送 } } void AlarmFSM::s0_on_exit() { CancelTimer(1); CancelTimer(2); } unsigned int AlarmFSM::s0_on_event( FSMEvent* event ) { if (event->iEvt == EVT_TIMER) { if(event->param1 == 1){ //改造为先判断是否不为空,再创建连接,减少空连接数 if(m_NewUploading_alarm.empty()){ //Dbg("no warn,wait 3s"); //DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM)("no warn,wait 3s"); ScheduleTimer(1, 3000);// try 3 seconds later }else{ if (!m_pConnection) { m_pConnection = new AlarmConnection(m_pEntity, this); if (m_pConnection->ConnectFromCentralSetting()&& m_pConnection->IsConnectionOK()) { //创建成功 }else{ //创建失败 Dbg("connect server fail,config or Servers Error!"); closeClientConn();//断开连接 } } if (!m_pConnection) { ScheduleTimer(1, 10000); // try 10 seconds later } else { PostEventLIFO(new FSMEvent(USER_EVT_JMP_ALARMUP));//跳转S1状态 } } }else if(event->param1 == 2){ //新模式 //if(m_NewUploading_alarm.empty()&&m_unSendAlarm.IsNullOrEmpty()){ // //DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM)("no warn,wait 3s"); // ScheduleTimer(2, 3000);// try 3 seconds later //}else{ //开始启动调用发送线程 Task::SendAlarmTask* alarmTask = new Task::SendAlarmTask(this); ErrorCodeEnum rc = m_pEntity->GetFunction()->PostThreadPoolTask(alarmTask); if(rc!=Error_Succeed){ DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM)("s0 create SendAlarmTask is fail,%d",(int)rc); ScheduleTimer(2, 10*1000);//等待一段时间 } //} } }else if (event->iEvt == USER_EVT_JMP_NEW_ALARM){ //if(m_NewUploading_alarm.empty()&&m_unSendAlarm.IsNullOrEmpty()){ // //DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM)("no warn,wait 3s"); // ScheduleTimer(2, 3000);// try 3 seconds later //}else{ //开始启动调用发送线程 Task::SendAlarmTask* alarmTask = new Task::SendAlarmTask(this); ErrorCodeEnum rc = m_pEntity->GetFunction()->PostThreadPoolTask(alarmTask); if(rc!=Error_Succeed){ DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM)("s0 create SendAlarmTask is fail,%d",(int)rc); ScheduleTimer(2, 10*1000);//等待一段时间 } //} } //else if (event->iEvt == USER_EVT_SEND_ALARM){ // SendAlarmEvent* pEvent = (SendAlarmEvent*)event; // if(pEvent->isSucc){ // //成功 // DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM)("send alarm statistic m_iRec=%d , m_iThrow=%d , UnSend=%d , m_iSucc=%d , m_iFail=%d",m_iRec,m_iThrow,m_NewUploading_alarm.size(),m_iSucc,m_iFail); // if(!m_NewUploading_alarm.empty()){ // ScheduleTimer(2,2000); // }else{ // ScheduleTimer(2,3000); // } // }else{ // //失败 // //超过未发送成功的告警时间间隔,丢弃告警信息 // CSmallDateTime endTime = CSmallDateTime::GetNow(); // if(((DWORD)endTime-(DWORD)m_sendBeginTime)>m_maxResendTime){ // m_unSendAlarm="";//置为空 // m_iFail = m_iFail+ m_eachSum ;//发送失败 // LogWarn(Severity_Low,Error_Exception,WARN_ALARM_SEND_FAIL,CSimpleStringA::Format("throw away alarm num= %d,m_iFail=%d",m_eachSum,m_iFail)); // m_eachSum =0;//清空批次数量 // m_sendBeginTime = CSmallDateTime::GetNow(); // DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM)("send alarm statistic m_iRec=%d , m_iThrow=%d , UnSend=%d , m_iSucc=%d , m_iFail=%d",m_iRec,m_iThrow,m_NewUploading_alarm.size(),m_iSucc,m_iFail); // } // ScheduleTimer(2,10000); // } //} return 0; } void AlarmFSM::s1_on_entry() { //connect //if (!m_pConnection) //{ // m_pConnection = new AlarmConnection(m_pEntity, this); // if (!m_pConnection->ConnectFromCentralSetting()) // { // Dbg("connect server fail,config or Servers Error!"); // PostEventLIFO(new FSMEvent(USER_EVT_DISCONNECT)); // return; // } //} //if (m_pConnection->IsConnectionOK()) //upload //{ // EnterCriticalSection(&cs); // alarm_t*alarm = list_first_entry(&m_uploading_alarm,alarm_t,entry); // if (alarm == NULL) // { // Dbg("get alarm error"); // PostEventLIFO(new FSMEvent(USER_EVT_JMP_RELEASE)); // } // m_pConnection->SendAlarm(alarm); // //add by zl 20180306, 添加到历史告警列表 // add_UploadedAlarm(alarm); // list_del(&alarm->entry); // //delete alarm->Description; // //delete alarm->EntityName; // //delete alarm->SN; // //delete alarm; // //因使用malloc创建内存,用free释放 // free(alarm->Description); // alarm->Description=NULL; // free(alarm->EntityName); // alarm->EntityName=NULL; // free(alarm->SN); // alarm->SN=NULL; // delete alarm; // alarm=NULL; // Dbg("send alarm success"); // PostEventLIFO(new FSMEvent(USER_EVT_JMP_RELEASE)); // LeaveCriticalSection(&cs); //} //else //{ // //链接失效,需要先释放并清空链接,否一直不会重连 // m_pConnection->Close(); // m_pConnection->DecRefCount(); // m_pConnection = NULL; // PostEventLIFO(new FSMEvent(USER_EVT_JMP_RELEASE)); //} if(m_NewUploading_alarm.empty()){ PostEventLIFO(new FSMEvent(USER_EVT_DISCONNECT_FAIL));//为空时,跳回S0状态 }else{ //Dbg("send alarm statistic m_iRec=%d , m_iThrow=%d , UnSend=%d , m_iSend=%d , m_iSucc=%d , m_iFail=%d",m_iRec,m_iThrow,m_NewUploading_alarm.size(),m_iSend,m_iSucc,m_iFail); DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM)("send alarm statistic m_iRec=%d , m_iThrow=%d , UnSend=%d , m_iSend=%d , m_iSucc=%d , m_iFail=%d",m_iRec,m_iThrow,m_NewUploading_alarm.size(),m_iSend,m_iSucc,m_iFail); m_iEachSend = 0; //发送告警信息 if(SendAlarm()){ m_iEachSend++;//发送成功 }else{ PostEventLIFO(new FSMEvent(USER_EVT_DISCONNECT));//发送失败时,跳回S0状态 } } } void AlarmFSM::s1_on_exit() { CancelTimer(2); } unsigned int AlarmFSM::s1_on_event(FSMEvent* event) { //if (event->iEvt == USER_EVT_DISCONNECT) //{ // Dbg("rx disconnect evt at alarmupload s1"); // if (m_pConnection) // { // m_pConnection->Close(); // m_pConnection->DecRefCount(); // m_pConnection = NULL; // ScheduleTimer(2, 5000); // } //} //else if (event->iEvt == EVT_TIMER) //{ // if (!m_pConnection) // { // m_pConnection = new AlarmConnection(m_pEntity, this); // if (!m_pConnection->ConnectFromCentralSetting()) // { // Dbg("connect server fail,config or Servers Error!"); // PostEventLIFO(new FSMEvent(USER_EVT_DISCONNECT)); // } // } //} //else if (event->iEvt == EVT_TIMER) //{ // //继续发送 //} if (event->iEvt == USER_EVT_DISCONNECT_FAIL) { //Dbg("disconnect 10s at alarmupload s1"); DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM)("disconnect 5s at alarmupload s1"); closeClientConn();//断开连接 ScheduleTimer(2, 5000); // try 5 seconds later } else if (event->iEvt == USER_EVT_DISCONNECT_SUCC) { //Dbg("disconnect 3s at alarmupload s1"); DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM)("disconnect 2s at alarmupload s1"); closeClientConn();//断开连接 ScheduleTimer(2, 2000); // try 2 seconds later } else if (event->iEvt == EVT_TIMER) { PostEventLIFO(new FSMEvent(USER_EVT_JMP_START));//跳转S0状态 } else if (event->iEvt ==USER_EVT_UPLOAD_ANS) { if(m_iEachSend<=50) { if(!m_NewUploading_alarm.empty()){ if(SendAlarm()){ m_iEachSend++;//发送成功 }else{ PostEventLIFO(new FSMEvent(USER_EVT_DISCONNECT_FAIL));//发送失败时,跳回S0状态 } }else{ PostEventLIFO(new FSMEvent(USER_EVT_DISCONNECT_FAIL));//为空时,跳回S0状态 } } else { PostEventLIFO(new FSMEvent(USER_EVT_DISCONNECT_SUCC));//达到一定发送数量,主动断开,跳回S0状态 } } return 0; } void AlarmFSM::s2_on_entry() { //connect if (!m_pConnection) { m_pConnection = new AlarmConnection(m_pEntity, this); if (!m_pConnection->ConnectFromCentralSetting()) { //Dbg("connect server fail,config or Servers Error!"); DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM)("connect server fail,config or Servers Error!"); } } if (m_pConnection->IsConnectionOK()) //upload alarm state { if (m_b_alarmstate) { m_pConnection->SendAlarmState(&m_uploading_alarmstate); //Dbg("send alarmstate success"); DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM)("send alarmstate success"); delete m_uploading_alarmstate.Description; PostEventLIFO(new FSMEvent(USER_EVT_JMP_RELEASE)); } } else { //链接失效,需要先释放并清空链接,否则一直不会重连 m_pConnection->Close(); m_pConnection->DecRefCount(); m_pConnection = NULL; PostEventLIFO(new FSMEvent(USER_EVT_JMP_RELEASE)); } } void AlarmFSM::s2_on_exit() { m_b_alarmstate = FALSE; CancelTimer(3); } unsigned int AlarmFSM::s2_on_event(FSMEvent* event) { if (event->iEvt == USER_EVT_DISCONNECT) { //Dbg("rx disconnect evt at alarm upload s2"); DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM)("rx disconnect evt at alarm upload s2"); if (m_pConnection) { m_pConnection->Close(); m_pConnection->DecRefCount(); m_pConnection = NULL; } ScheduleTimer(3, 10000); } return 0; } void AlarmFSM::s3_on_entry() { //modify by zl 20180314,发送完,马上断开链接可能会导致服务端无法接受到请求,改用长链接 /*if (m_pConnection) { m_pConnection->Close(); m_pConnection->DecRefCount(); m_pConnection = NULL; LogEvent(Severity_Low,EVENT_MOD_ALARM_INITIATIVE_DISCONNECT,"Connecting Closed"); }*/ PostEventFIFO(new FSMEvent(USER_EVT_DISCONNECT)); if (!m_pConnection) { ScheduleTimer(4, 1000); // try 30 seconds later } } void AlarmFSM::s3_on_exit() { CancelTimer(4); } unsigned int AlarmFSM::s3_on_event(FSMEvent* event) { if (event->iEvt == USER_EVT_DISCONNECT) { //Dbg(" disconnect evt at alarm upload s3"); DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM)("disconnect evt at alarm upload s3"); /*if (m_pConnection) { m_pConnection->Close(); m_pConnection->DecRefCount(); m_pConnection = NULL; }*/ } return 0; } //增加告警 void AlarmFSM::add_alarm(alarm_t*alarm) { EnterCriticalSection(&cs); add_new_alarm(alarm,&m_uploading_alarm); LeaveCriticalSection(&cs); } //设置告警状态 void AlarmFSM::set_alarm_state(const CUUID nLogID,DWORD LifeId,const SeverityLevelEnum eLevel, DWORD Item,const char *pszMessage) { m_uploading_alarmstate.SN = nLogID; _itoa((int)eLevel,&m_uploading_alarmstate.Level,16); m_uploading_alarmstate.LifeID = LifeId; m_uploading_alarmstate.Item = Item; char cDescription[512]; strcpy(cDescription,pszMessage); m_uploading_alarmstate.Description = _strdup(cDescription); m_b_alarmstate = TRUE; } //获取告警数量 bool AlarmFSM::is_alarm_empty() { EnterCriticalSection(&cs); bool i = list_empty(&m_uploading_alarm); LeaveCriticalSection(&cs); return i; } bool AlarmFSM::is_UploadedAlarm_empty() { EnterCriticalSection(&cs); bool i = list_empty(&m_uploaded_alarm); LeaveCriticalSection(&cs); return i; } static time_t NowTime() { time_t t_Now = time(0); struct tm* tm_Now = localtime(&t_Now); /*tm_Now->tm_hour =0; tm_Now->tm_min = 0; tm_Now->tm_sec = 0;*/ return mktime(tm_Now); } void AlarmFSM::add_UploadedAlarm(alarm_t*alarm) { alarmUpgraded_t*upedAlarm = new alarmUpgraded_t(); upedAlarm->EntityName = new char[32]; if (NULL != upedAlarm->EntityName) { memset(upedAlarm->EntityName, 0, 32); } upedAlarm->SN = new char[20]; if (NULL != upedAlarm->SN) { memset(upedAlarm->SN, 0, 20); } upedAlarm->Description = new char[512]; if (NULL != upedAlarm->Description) { memset(upedAlarm->Description, 0, 512); } strcpy(upedAlarm->EntityName,alarm->EntityName); strcpy(upedAlarm->SN,alarm->SN); upedAlarm->LifeID = alarm->LifeID; upedAlarm->Item = alarm->Item; upedAlarm->UserCode = alarm->UserCode; upedAlarm->Level = alarm->Level; strcpy(upedAlarm->Description,alarm->Description); upedAlarm->time = NowTime(); //如果是相同实体且相同描述,则更新告警。否则做为新告警添加 if (!update_UploadedAlarm(upedAlarm)) { EnterCriticalSection(&cs); add_new_upalarm(upedAlarm,&m_uploaded_alarm); LeaveCriticalSection(&cs); } } bool AlarmFSM::find_UploadedAlarm(alarm_t*alarm) { EnterCriticalSection(&cs); if (is_UploadedAlarm_empty()) { return false; } //time_t tNow = NowTime(); //获取时间报错,改为直接获取 time_t t_Now = time(0); struct tm* tm_Now = localtime(&t_Now); time_t tNow = mktime(tm_Now); //Dbg("tNow[%d]", tNow); alarmUpgraded_t* uploadedAlarm; list_for_each_entry(uploadedAlarm, &m_uploaded_alarm, alarmUpgraded_t, entry) { if (0 == strcmp(uploadedAlarm->EntityName, alarm->EntityName) && 0 == strcmp(uploadedAlarm->Description, alarm->Description)) { if (tNow > uploadedAlarm->time) { UINT nSecond = tNow - uploadedAlarm->time; UINT nMin = nSecond/60; if (nMin <= m_nDealWarningTime) { //在指定时间内(可配置),收到同一实体的同一告警,去重 //Dbg("find same uploaded alarm list, don't need to send again"); DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM).setAPI("find_UploadedAlarm")("find same uploaded alarm list, don't need to send again"); return true; } } else { //Dbg("uploadedAlarm->time[%d] >= tNow[%d], time is wrong", uploadedAlarm->time, tNow); DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM).setAPI("find_UploadedAlarm")("uploadedAlarm->time[%d] >= tNow[%d], time is wrong", uploadedAlarm->time, tNow); } } } LeaveCriticalSection(&cs); return false; } bool AlarmFSM::update_UploadedAlarm(alarmUpgraded_t*alarm) { EnterCriticalSection(&cs); if (is_UploadedAlarm_empty()) { return false; } alarmUpgraded_t* uploadedAlarm; list_for_each_entry(uploadedAlarm, &m_uploaded_alarm, alarmUpgraded_t, entry) { if (0 == strcmp(uploadedAlarm->EntityName, alarm->EntityName) || 0 == strcmp(uploadedAlarm->Description, alarm->Description)) { update_upalarm(alarm, uploadedAlarm); //替换后,旧的对象需要清理 //free(uploadedAlarm->Description); //free(uploadedAlarm->EntityName); //free(uploadedAlarm->SN); delete[] uploadedAlarm->Description; uploadedAlarm->Description=NULL; delete[] uploadedAlarm->EntityName; uploadedAlarm->EntityName=NULL; delete[] uploadedAlarm->SN; uploadedAlarm->SN=NULL; delete uploadedAlarm; uploadedAlarm=NULL; return true; } } LeaveCriticalSection(&cs); return false; } //增加消息到新告警列表 void AlarmFSM::add_NewAlarm(alarm_t* alarm) { EnterCriticalSection(&cs); if(m_NewUploading_alarm.size()>=UPLOG_MAX_COUNT){ //Dbg("队列已满,删除首元素"); m_iThrow++; alarm_t* oldAlarm = (alarm_t*)(*m_NewUploading_alarm.begin());//集合首个元素 m_NewUploading_alarm.erase(m_NewUploading_alarm.begin());//集合删除首元素 free(oldAlarm->Description); oldAlarm->Description=NULL; free(oldAlarm->EntityName); oldAlarm->EntityName=NULL; free(oldAlarm->SN); oldAlarm->SN=NULL; free(oldAlarm->warnTime); oldAlarm->warnTime=NULL; delete oldAlarm; oldAlarm=NULL; } m_NewUploading_alarm.push_back(alarm);//加入队列 LeaveCriticalSection(&cs); } //取出消息从新告警列表 alarm_t* AlarmFSM::removeAlarm() {//加锁,取出先进的队列日志,注意释放内存空间 alarm_t* dAlarm = NULL; EnterCriticalSection(&cs); if(m_NewUploading_alarm.empty()){ //return NULL; }else{ dAlarm = (alarm_t*)(*m_NewUploading_alarm.begin());//集合首个元素 m_NewUploading_alarm.erase(m_NewUploading_alarm.begin());//集合删除首元素 } LeaveCriticalSection(&cs); return dAlarm;//返回 } //关闭连接 void AlarmFSM::closeClientConn() { if(m_pConnection!=NULL){ m_pConnection->Close(); m_pConnection->DecRefCount(); m_pConnection = NULL; } } //发送新告警信息 bool AlarmFSM::SendAlarm(){ alarm_t*alarm = removeAlarm(); if (alarm == NULL) { //Dbg("get alarm error"); DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM).setAPI("SendAlarm")("get alarm error"); return false; } m_iSend++;//发送计数 m_pConnection->SendAlarm(alarm); free(alarm->Description); alarm->Description=NULL; free(alarm->EntityName); alarm->EntityName=NULL; free(alarm->SN); alarm->SN=NULL; free(alarm->warnTime); alarm->warnTime=NULL; delete alarm; alarm=NULL; return true; } void AlarmFSM::HttpsLogCallBack(const char* logtxt) { DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM).setAPI("HttpsLogCallBack")("http dbg: %s",logtxt); } std::string AlarmFSM::alarmJson() { vector unSendAlarm; string jsonStr =""; EnterCriticalSection(&cs); alarm_t* dAlarm = NULL; for(int i = 0 ;i<16;i++){ if(m_NewUploading_alarm.empty()){ break; }else{ dAlarm = (alarm_t*)(*m_NewUploading_alarm.begin());//集合首个元素 m_NewUploading_alarm.erase(m_NewUploading_alarm.begin());//集合删除首元素 unSendAlarm.push_back(dAlarm); } } LeaveCriticalSection(&cs); if(unSendAlarm.size()==0){ return jsonStr;//无发送直接返回空 } Json::Value root; Json::Value arraylist;//消息列表 Json::FastWriter fw;//写入对象 int i = 0; CSystemStaticInfo si; { m_pEntity->GetFunction()->GetSystemStaticInfo(si); } for(auto iter = unSendAlarm.begin(); iter!=unSendAlarm.end(); iter++){ Json::Value rootAlarm; Json::FastWriter fwAlarm;//写入对象 alarm_t* alarmt = *iter; m_uuid =CUUID::Create(m_uuid); rootAlarm["IDKey"] = m_uuid.ToString().GetData(); rootAlarm["BranchNo"] = m_branchNo.GetData(); rootAlarm["TerminalNo"] = si.strTerminalID.GetData(); rootAlarm["EntityName"] = alarmt->EntityName; rootAlarm["Item"] = CSimpleStringA::Format("%016llx", alarmt->Item).SubString(8,8).GetData();//16进制取后面八位 char Level[2]; sprintf(Level, "%c", alarmt->Level); rootAlarm["Level"] = CSimpleStringA::Format("%s",Level).GetData(); rootAlarm["LifeID"] = CSimpleStringA::Format("%016llx", alarmt->LifeID).SubString(8,8).GetData();//16进制取后面八位 rootAlarm["SN"] = alarmt->SN; rootAlarm["UserCode"] = CSimpleStringA::Format("%016llx", alarmt->UserCode).SubString(8,8).GetData();//16进制取后面八位 rootAlarm["WarningTime"] = CSimpleStringA::Format("%s", alarmt->warnTime).GetData(); rootAlarm["Description"] = CSimpleStringA::Format("%s", alarmt->Description).GetData(); //增加终端版本号字段 rootAlarm["VersionNo"] = si.InstallVersion.ToString().GetData(); string alarmJsonStr = fwAlarm.write(rootAlarm); //DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM)("alarmJsonStr=%s",alarmJsonStr.c_str()); arraylist[i]=alarmJsonStr.c_str(); i++; } root["message_list"] = arraylist; root["topic"]=m_topic.GetData(); jsonStr = fw.write(root); m_eachSum = i; //清理内存 while(true){ if(unSendAlarm.empty()){ break; }else{ dAlarm = (alarm_t*)(*unSendAlarm.begin());//集合首个元素 unSendAlarm.erase(unSendAlarm.begin());//集合删除首元素 } free(dAlarm->Description); dAlarm->Description=NULL; free(dAlarm->EntityName); dAlarm->EntityName=NULL; free(dAlarm->SN); dAlarm->SN=NULL; free(dAlarm->warnTime); dAlarm->warnTime=NULL; delete dAlarm; dAlarm=NULL; } return jsonStr; } #ifdef RVC_OS_WIN #else int AlarmFSM::HexBuf2StrBuf(PBYTE hexBuf, char** strBuf, DWORD len) { char* tmpStr = *strBuf; int count = 0; for (int i = 0; i < len; ++i) { sprintf(tmpStr + count, "%0.2x", hexBuf[i]); Dbg("strBut:%s", tmpStr); count += 2; } return 0; } #endif