fast/Platform/ModuleProcess.cpp
2025-01-20 10:30:01 +08:00

286 lines
6.2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "StdAfx.h"
#include "Agv.h"
#include "ModuleProcess.h"
#include "AgvMainDialog.h"
int g_ulTerminal = 0;
void g_PipeCallBack(void* pObj, int lMsgId, WPARAM wparam, LPARAM lparam)
{
CModuleProcess* pModule = (CModuleProcess*)pObj;
pModule->PipeCallBack(lMsgId, wparam, lparam);
}
CModuleProcess::CModuleProcess(CAgvMainDialog *pMainWnd, CString strModulePath, CString strModuleName, int lModuleIndex)
{
m_lModuleIndex = lModuleIndex;
m_strModulePath = strModulePath;
m_strModuleName = strModuleName;
m_hProcessManageThr = NULL;
m_bAcitv = FALSE;
m_hWnd = pMainWnd->m_hWnd;
m_pAgvMainWnd = pMainWnd;
m_bIsConnectModule = FALSE;
m_lReStartCount = 0;
m_lState = 0;
ZeroMemory(&m_pi,sizeof(m_pi)); //此参数必须清零
m_pstPipeServer = CCEXPipeServerBase::CreateObj();
m_nDebug = 0;
}
CModuleProcess::~CModuleProcess(void)
{
if (NULL != m_pstPipeServer)
{
delete m_pstPipeServer;
}
}
unsigned int __stdcall g_ProcessManageThr(void* pParam)
{
((CModuleProcess*)pParam)->ProcessManageThr();
return 0;
}
//启动模块
BOOL CModuleProcess::Start(int nDebug)
{
m_nDebug = nDebug;
if (NULL != m_hProcessManageThr)
{
return FALSE;
}
if (m_strPipeName.IsEmpty())
{
return FALSE;
}
m_bAcitv = TRUE;
if (m_nDebug == 1)
{
if (NULL == m_pstPipeServer)
{
//常规参数检查
return FALSE;
}
m_pstPipeServer->RegisterCall(g_PipeCallBack, this);
m_pstPipeServer->Start(m_strPipeName);
return TRUE;
}
m_hProcessManageThr = (HANDLE)_beginthreadex(NULL, 0, g_ProcessManageThr, this, 0, NULL);
return TRUE;
}
//停止模块
void CModuleProcess::Stop()
{
if (NULL == m_hProcessManageThr)
{
LogOutToFile("CModuleProcess::Stop() already stop. [%s]", m_strModulePath);
return ;
}
LogOutToFile("CModuleProcess::Stop() bg [%s]", m_strModulePath);
m_bAcitv = FALSE;
if (m_pstPipeServer->IsConnect())
{
//如果子模块有连接管道,则只需要关闭自身端口,子模块检测到平台端关闭后就会直接退出
m_pstPipeServer->Stop();
}
else
{
//m_pstPipeServer->Stop();
//若子模块未连接平台,则子模块无法检测平台的关闭,这里强制把子模块结束了
TerminateProcess(m_pi.hProcess, 0);
}
if (WAIT_TIMEOUT == WaitForSingleObject(m_hProcessManageThr, 5000))
{
TerminateProcess(m_pi.hProcess, 0);
Sleep(500);
LogOutToFile("CModuleProcess::Stop() timeout [%s]", m_strModulePath);
TerminateThread(m_hProcessManageThr, 0);
}
else
{
LogOutToFile("CModuleProcess::Stop() succ[%s]", m_strModulePath);
}
m_hProcessManageThr = NULL;
return;
}
int CModuleProcess::GetStatus()
{
if (NULL == m_hProcessManageThr)
{
return 0;
}
return m_lState;
}
//发送数据到模块进程
BOOL CModuleProcess::SendDataToModule(int lMsgId, const char* pData, int lLen)
{
if (NULL == m_pstPipeServer)
{
return FALSE;
}
m_pstPipeServer->SendeMsg(lMsgId, pData, lLen);
return TRUE;
}
//和模块进程通讯的管道回调函数:
//1、lparam > 0时wparam为数据内容lparam为数据长度
//2、lparam-1管道连接成功-2管道断开-3管道异常
void CModuleProcess::PipeCallBack(int lMsgId, WPARAM wparam, LPARAM lparam)
{
if (CEXPIPE_NEW_DATA == lMsgId)
{
PIPE_DATA_STRUCT* pPipeData = (PIPE_DATA_STRUCT*)wparam;
if (pPipeData->lDataLen + sizeof(PIPE_DATA_STRUCT) - sizeof(char[4]) != (int)lparam)
{
return ;//数据通讯异常
}
Json::Reader reader;
Json::Value root;
CString strData = "data=";
if (reader.parse(pPipeData->acData, root))
{
CString strSender = root["sender"].asString().c_str();
CString strReceiver = root["receiver"].asString().c_str();
//WCS->WMS的消息
if (strReceiver == "WMS")
{
m_httpClent.GenericPost(strData + pPipeData->acData);
CString strMsg = "发送给WMS的消息:";
strMsg += pPipeData->acData;
m_pAgvMainWnd->AddLog2Edit(strMsg);
}
else //插件间消息
{
CModuleProcess *pModuleProcess = m_pAgvMainWnd->GetModuleByName(strReceiver);
if (NULL != pModuleProcess)
{
pModuleProcess->SendDataToModule(MAIN_2_MODULE_WMS, pPipeData->acData, pPipeData->lDataLen);
CString strMsg = "转发给Plugin的消息:";
strMsg += pPipeData->acData;
m_pAgvMainWnd->AddLog2Edit(strMsg);
}
}
}
}
else if (CEXPIPE_DIS_CLIENT == lMsgId)
{
//管道断开,结束
//PostMessage(WM_CLOSE, NULL, NULL);
TRACE("子模块已断开\r\n");
}
else if (CEXPIPE_NEW_CLIENT == lMsgId)
{
//连接成功
//PostMessage(WM_PIPE_CONNECT_OK, NULL, NULL);
PostMessage(m_hWnd, WM_MODULE_CONNECT_ID, (WPARAM)this, NULL);
TRACE("子模块已连接\r\n");
}
else
{
TRACE("异常管道消息[%d]\r\n", lMsgId);
}
return;
}
void CModuleProcess::ProcessManageThr()
{
int lDelay = 3000;
for (; TRUE == m_bAcitv;)
{
m_lReStartCount++;
m_lState = 1;
PostMessage(m_hWnd, WM_UPDATE_MODULE_STATUS, NULL, NULL);
if (FALSE == StartModule())
{
//lDelay *= 2;//错误一次下次启动延迟双倍时间
}
m_lState = 2;
PostMessage(m_hWnd, WM_UPDATE_MODULE_STATUS, NULL, NULL);
TRACE("子模块异常退出,延迟[%d ms]重启\r\n", lDelay);
for (int i = 0; i < lDelay && TRUE == m_bAcitv; i+=20)
{
Sleep(20);
}
}
}
BOOL CModuleProcess::StartModule()
{
if (NULL == m_pstPipeServer)
{
//常规参数检查
return FALSE;
}
if (m_pstPipeServer->IsAcitve())
{
//模块已经启动
return FALSE;
}
//Stop();
m_pstPipeServer->RegisterCall(g_PipeCallBack, this);
m_pstPipeServer->Start(m_strPipeName);
STARTUPINFO si; //启动进程参数
CString strCommend;
strCommend.Format("-u %u -pipe %s", g_ulTerminal, m_strPipeName.GetBuffer());
//结构清零
ZeroMemory(&si,sizeof(si)); //此参数必须清零
ZeroMemory(&m_pi,sizeof(m_pi)); //此参数必须清零
si.dwFlags =STARTF_USESHOWWINDOW;//隐藏创建的窗口
si.wShowWindow=SW_SHOW;//隐藏创建的窗口
//Sleep(999999999);
if(FALSE == CreateProcess(m_strModulePath.GetBuffer(), strCommend.GetBuffer(), NULL, NULL, false, 0, NULL, NULL, &si, &m_pi))
{
ZeroMemory(&m_pi,sizeof(m_pi)); //此参数必须清零
LogOutToFile("应用启动失败:%s[%s]", m_strModulePath.GetBuffer(), strCommend.GetBuffer());
m_pstPipeServer->Stop();
return FALSE;
}
LogOutToFile("[info] 模块启动完成[%s][%s]", m_strModulePath, strCommend.GetBuffer());
TRACE("[info] 模块启动完成[%s][%s]", m_strModulePath, strCommend.GetBuffer());
//应用非正常退出都认为是错误情况
if (WAIT_OBJECT_0 != WaitForSingleObject(m_pi.hThread, INT_MAX))
{
m_pstPipeServer->Stop();
return FALSE;
}
m_pstPipeServer->Stop();
return TRUE;
}