#include "stdafx.h" #include "PduMain.h" #include "PduSocketVector.h" #include "PduSocket.h" #include "PduSocketServer.h" #include "PduEventHost.h" #include "PduEntity.h" CPduMain* CPduMain::m_pInstance = NULL; CPduMain::CPduMain(void) { if (!AfxSocketInit()) AfxMessageBox("AfxSocketInit执行失败"); m_pSocketServer = NULL; m_pSocketVector = new CPduSocketVector(); m_pEventHost = new CPduEventHost(); m_nDevType = PDU_DEV_TYPE_UNKNOWN; m_nDevId = 0; } CPduMain::~CPduMain(void) { StopAll(); } /***************************************************************** **【函数名称】 getCommInstance **【函数功能】 得到消息通讯接口实例 **【参数】 **【返回值】 ****************************************************************/ IPduComm* CInterfaceWindow::getCommInstance() { return CPduMain::getInstance(); } /***************************************************************** **【函数名称】 getLinkInstance **【函数功能】 得到消息通讯接口实例 **【参数】 **【返回值】 ****************************************************************/ IPduLink* CInterfaceWindow::getLinkInstance() { return CPduMain::getInstance(); } /***************************************************************** **【函数名称】 getInstance **【函数功能】 得到接口指针 **【参数】 **【返回值】 ****************************************************************/ CPduMain* CPduMain::getInstance() { if(NULL == m_pInstance) { m_pInstance = new CPduMain(); } // end if return m_pInstance; } /***************************************************************** **【函数名称】 SetLocalInfo **【函数功能】 设定PDU本端设备类型及ID **【参数】 a_nDevType 本端设备类型 a_nDevId 本端设备ID **【返回值】 ****************************************************************/ void CPduMain::SetLocalInfo(PDU_DEV_TYPE a_nDevType, int a_nDevId) { m_nDevType = a_nDevType; m_nDevId = a_nDevId; } /***************************************************************** **【函数名称】 GetLocalInfo **【函数功能】 读取PDU本端设备类型及ID **【参数】 **【返回值】 a_nDevType 本端设备类型 a_nDevId 本端设备ID ****************************************************************/ void CPduMain::GetLocalInfo(PDU_DEV_TYPE& a_nDevType, int& a_nDevId) { a_nDevType = m_nDevType; a_nDevId = m_nDevId; } /***************************************************************** **【函数名称】 SetLinkContent **【函数功能】 生成连接信息内容 **【参数】 a_nLinkInfo SOCKET连接状态 a_npSocket 关联的SOCKET实例 **【返回值】 linkContent ****************************************************************/ void CPduMain::SetLinkContent(PduLinkContent& linkContent, PDU_LINK_STATE a_nLinkInfo, CPduSocket* a_pSocket) { memset(&linkContent, 0, sizeof(PduLinkContent)); CString strIp = _T(""); linkContent.nLocalType = m_nDevType; linkContent.nLocalId = m_nDevId; linkContent.nLinkState = a_nLinkInfo; a_pSocket->GetPeerLinkInfo(strIp, linkContent.nFarPort); a_pSocket->GetPeerDevInfo(linkContent.nFarType, linkContent.nFarId); lstrcpy(linkContent.szFarIp, strIp); } /***************************************************************** **【函数名称】 CreatePduServer **【函数功能】 创建PDU通讯服务器 **【参数】 a_nListenPort SOCKET监听端口 a_nLocalType 服务器设备类型 a_nLocalId 服务器设备ID **【返回值】 ****************************************************************/ BOOL CPduMain::CreatePduServer(int a_nListenPort, PDU_DEV_TYPE a_nLocalType, int a_nLocalId) { m_pSocketServer = new CPduSocketServer(this); // 启动SOCKET SERVER if(m_pSocketServer->Init(a_nListenPort)) { SetLocalInfo(a_nLocalType, a_nLocalId); return TRUE; } else { delete m_pSocketServer; m_pSocketServer = NULL; } // end if return FALSE; } /***************************************************************** **【函数名称】 CreatePduClient **【函数功能】 创建PDU通讯客户端 **【参数】 a_strFarIp 要连接的服务器IP a_nFarPort 要连接的服务器端口号 a_nLocalType 本端设备类型 a_nLocalId 本端设备ID a_nFarType 对端设备类型 a_nFarId 对端设备ID **【返回值】 TRUE 启动连接成功 FALSE 启动连接失败 ****************************************************************/ BOOL CPduMain::CreatePduClient(CString a_strFarIp, int a_nFarPort, PDU_DEV_TYPE a_nLocalType, int a_nLocalId, PDU_DEV_TYPE a_nFarType, int a_nFarId, bool IsAutoReconnect) { // 如果已存在到对端的连接 CPduSocket* pSocket = m_pSocketVector->GetPduSocket(a_nFarType, a_nFarId); if(pSocket != NULL) return FALSE; // 开始连接 pSocket = new CPduSocket(this, PDU_LINK_TYPE_CLIENT, IsAutoReconnect); if(pSocket->ConnectToServer(a_strFarIp, a_nFarPort, a_nFarType, a_nFarId)) { m_pSocketVector->InsertSocket(pSocket); SetLocalInfo(a_nLocalType, a_nLocalId); return TRUE; } else { delete pSocket; } // end if return FALSE; } /***************************************************************** **【函数名称】 ClosePduClient **【函数功能】 关闭PDU通讯客户端 **【参数】 a_nFarType 对端设备类型 a_nFarId 对端设备ID **【返回值】 TRUE 启动连接成功 FALSE 启动连接失败 ****************************************************************/ BOOL CPduMain::ClosePduClient(PDU_DEV_TYPE a_nFarType, int a_nFarId) { return m_pSocketVector->RemoveSocket(a_nFarType, a_nFarId); } /***************************************************************** **【函数名称】 Send **【函数功能】 发送PDU命令 **【参数】 a_pCmd 要发送的命令实体 a_nDestType 消息要发送的目标设备类型 a_nDestId 消息要发送的目标设备ID **【返回值】 ****************************************************************/ BOOL CPduMain::Send(CPduEntity* a_pCmd, PDU_DEV_TYPE a_nDestType, int a_nDestId) { CPduSocket* pSocket = NULL; // 对注册命令的特殊处理 if(a_pCmd->GetCmdType() == PDU_CMD_REG && a_pCmd->GetIsExecReturn()) { // 查找要发送命令的连接 pSocket = m_pSocketVector->GetPduSocket(a_pCmd->GetAssoSocket()); if(pSocket == NULL) return FALSE; // 触发注册事件 if(a_pCmd->GetDataBool(0)) { pSocket->SetPeerDevInfo(a_nDestType, a_nDestId); OnConnRegistOK(pSocket); } else { OnConnRegistFailed(pSocket); } // end if } else { // 查找要发送命令的连接 pSocket = m_pSocketVector->GetPduSocket(a_nDestType, a_nDestId); if(pSocket == NULL) return FALSE; } // end if // 发送命令 a_pCmd->SetLocalDevInfo(m_nDevType, m_nDevId); // 填充发送方信息 a_pCmd->SetPeerDevInfo(a_nDestType, a_nDestId); // 填充接收方信息 return pSocket->SendDirectly(a_pCmd); } /***************************************************************** **【函数名称】 Send2All **【函数功能】 向所有注册过的客户端发送PDU **【参数】 **【返回值】 ****************************************************************/ void CPduMain::Send2All( CPduEntity* a_pCmd ) { a_pCmd->SetLocalDevInfo(m_nDevType, m_nDevId); // 填充发送方信息 m_pSocketVector->Send2All(a_pCmd); } /***************************************************************** **【函数名称】 GetLinkInfo **【函数功能】 获取指定连接的网络信息 **【参数】 OUT a_strIp 指定连接的对端IP OUT a_nPort 指定连接的对端PORT IN a_nType 要查询的连接类型 IN a_nId 要查询的连接ID **【返回值】 ****************************************************************/ BOOL CPduMain::GetLinkInfo(CString& a_strIp, int& a_nPort, PDU_DEV_TYPE a_nType, int a_nId) { // 查找连接 CPduSocket* pSocket = m_pSocketVector->GetPduSocket(a_nType, a_nId); if(pSocket == NULL) return FALSE; // 获取连接的网络信息 pSocket->GetPeerLinkInfo(a_strIp, a_nPort); return TRUE; } /***************************************************************** **【函数名称】 GetPeerIp **【函数功能】 获取PDU命令的发送方IP **【参数】 OUT a_strIp 发送当前PDU命令的对端IP IN a_pCmd 当前接收到的PDU命令 **【返回值】 ****************************************************************/ BOOL CPduMain::GetPeerIp(CString& a_strIp, CPduEntity* a_pCmd) { CPduSocket* pSocket = m_pSocketVector->GetPduSocket(a_pCmd->GetAssoSocket()); if(pSocket == NULL) return FALSE; // 获取连接的网络信息 int nPort = 0; pSocket->GetPeerLinkInfo(a_strIp, nPort); return TRUE; } /***************************************************************** **【函数名称】 RegistPduLinkProc **【函数功能】 订阅连接管理事件 **【参数】 a_pPduLinkProc 要对事件进行处理的接口类 bIsInsert 添加/删除定阅 **【返回值】 ****************************************************************/ BOOL CPduMain::RegistPduLinkProc(IPduLinkProc* a_pPduLinkProc, BOOL bIsInsert) { return m_pEventHost->RegLinkProc(a_pPduLinkProc, bIsInsert); } /***************************************************************** **【函数名称】 RegistPduCommProc **【函数功能】 订阅消息通知事件 **【参数】 a_pPduCommProc 要对事件进行处理的接口类 bIsInsert 添加/删除定阅 **【返回值】 ****************************************************************/ BOOL CPduMain::RegistPduCommProc(IPduCommProc* a_pPduCommProc, BOOL bIsInsert) { return m_pEventHost->RegCommProc(a_pPduCommProc, bIsInsert); } /***************************************************************** **【函数名称】 OnConnEstablished **【函数功能】 初始连接建立的后续处理 **【参数】 **【返回值】 ****************************************************************/ void CPduMain::OnConnEstablished(CPduSocket* a_pSocket) { // 对SOCKET容器的处理 PDU_LINK_STATE nLinkState = m_pSocketVector->OnConnEstablished(a_pSocket); // 对事件观查者的处理 PduLinkContent linkContent; SetLinkContent(linkContent, nLinkState, a_pSocket); m_pEventHost->OnLinkStateChanged(linkContent); // 对SOCKET监控的处理 a_pSocket->OnConnEstablished(); } /***************************************************************** **【函数名称】 OnConnFailed **【函数功能】 初连接断开/失败的后续处理 **【参数】 **【返回值】 ****************************************************************/ void CPduMain::OnConnFailed(CPduSocket* a_pSocket) { // 对SOCKET容器的处理 PDU_LINK_STATE nLinkState = m_pSocketVector->OnConnFailed(a_pSocket); // 对SOCKET监控的处理 a_pSocket->OnConnFailed(); // 对事件观查者的处理 PduLinkContent linkContent; SetLinkContent(linkContent, nLinkState, a_pSocket); m_pEventHost->OnLinkStateChanged(linkContent); } /***************************************************************** **【函数名称】 OnConnRegistOK **【函数功能】 连接注册成功的后续处理 **【参数】 **【返回值】 ****************************************************************/ void CPduMain::OnConnRegistOK(CPduSocket* a_pSocket) { // 对SOCKET容器的处理 PDU_LINK_STATE nLinkState = m_pSocketVector->OnConnRegistOK(a_pSocket); // 对SOCKET监控的处理 a_pSocket->OnConnRegistOK(); // 对事件观查者的处理 PduLinkContent linkContent; SetLinkContent(linkContent, nLinkState, a_pSocket); m_pEventHost->OnLinkStateChanged(linkContent); } /***************************************************************** **【函数名称】 OnConnRegistFailed **【函数功能】 连接注册失败的后续处理 **【参数】 **【返回值】 ****************************************************************/ void CPduMain::OnConnRegistFailed(CPduSocket* a_pSocket) { // 对SOCKET容器的处理 PDU_LINK_STATE nLinkState = m_pSocketVector->OnConnRegistFailed(a_pSocket); // 对SOCKET监控的处理 a_pSocket->OnConnRegistFailed(); // 对事件观查者的处理 PduLinkContent linkContent; SetLinkContent(linkContent, nLinkState, a_pSocket); m_pEventHost->OnLinkStateChanged(linkContent); } /***************************************************************** **【函数名称】 OnRecvCommand **【函数功能】 命令接收的处理 **【参数】 a_pCmd 当前接收到的命令实体 **【返回值】 ****************************************************************/ void CPduMain::OnRecvCommand(CPduEntity* a_pCmd) { // 接收端校验 ASSERT((a_pCmd->GetPeerDevId() == (ULONG)m_nDevId && a_pCmd->GetPeerDevType() == (ULONG)m_nDevType)); // 对注册命令的特殊处理 if(a_pCmd->GetCmdType() == PDU_CMD_REG && a_pCmd->GetIsExecReturn()) { // 查找要接收命令的连接 CPduSocket* pSocket = m_pSocketVector->GetPduSocket(a_pCmd->GetAssoSocket()); if(pSocket == NULL) return; // 异常处理 // 触发注册事件 if(a_pCmd->GetDataBool(0)) { OnConnRegistOK(pSocket); } else { OnConnRegistFailed(pSocket); } // end if } // end if // 对事件观查者的处理 m_pEventHost->OnRecvCommand(a_pCmd); } /***************************************************************** **【函数名称】 StopAll **【函数功能】 停止 **【参数】 **【返回值】 ****************************************************************/ void CPduMain::StopAll( void ) { if(m_pSocketServer != NULL) { delete m_pSocketServer; m_pSocketServer = NULL; } if(m_pSocketVector != NULL) { m_pSocketVector->Release(); delete m_pSocketVector; m_pSocketVector = NULL; } if(m_pEventHost != NULL) { delete m_pEventHost; m_pEventHost = NULL; } }