Aucune description

NetworkIvr.cpp 6.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. #include "StdAfx.h"
  2. #include "NetworkIvr.h"
  3. #include "Config.h"
  4. #include "IvrCore.h"
  5. #include "MsgCenter.h"
  6. SINGLETON_IMPLEMENT(CNetworkIvr)
  7. CNetworkIvr::CNetworkIvr(void) : m_CtiDevID(0), m_IsCtiConnected(false)
  8. {
  9. }
  10. CNetworkIvr::~CNetworkIvr(void)
  11. {
  12. }
  13. /*****************************************************************
  14. **【函数名称】 init
  15. **【函数功能】 初始化
  16. **【参数】
  17. **【返回值】
  18. ****************************************************************/
  19. BOOL CNetworkIvr::init( void )
  20. {
  21. // 初始化命令配置
  22. #ifdef _DEBUG
  23. CPduDataFormat::getInstance()->Load("../NetLib/PDUFormat.ini"); //../NetLib/PDUFormat.ini
  24. #else
  25. CPduDataFormat::getInstance()->Load("./PDUFormat.ini");
  26. #endif
  27. /*
  28. // 注册事件响应接口
  29. IPduLink* pPduLink = CInterfaceWindow::getLinkInstance();
  30. IPduComm* pPduComm = CInterfaceWindow::getCommInstance();
  31. pPduLink->RegistPduLinkProc(this, TRUE);
  32. pPduComm->RegistPduCommProc(this, TRUE);
  33. CString CtiIp = CConfig::ctiIp();
  34. int CtiPort = CConfig::ctiPort();
  35. // 连接到CTI
  36. if(!pPduLink->CreatePduClient(CtiIp, CtiPort, PDU_DEV_TYPE_IVR, 0, PDU_DEV_TYPE_CTI, 0, true))
  37. {
  38. ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_ERROR, _T("{Network}: 连接CTI服务器[%s:%d]失败, 请检查网络配置是否正常"), CtiIp, CtiPort);
  39. return FALSE;
  40. } // end if
  41. */
  42. // 注册事件响应接口 2022-10-26 改用IOCP,保持和CTI,ACD一样
  43. CInterfaceWindow::getIocpLinkInstance()->RegistPduLinkProc(this, TRUE);
  44. CInterfaceWindow::getIocpCommInstance()->RegistPduCommProc(this, TRUE);
  45. CString CtiIp = CConfig::ctiIp();
  46. int CtiPort = CConfig::ctiPort();
  47. // 创建 SERVER
  48. int ListenPort = 8841;
  49. if (!CInterfaceWindow::getIocpLinkInstance()->CreatePduServer(ListenPort, PDU_DEV_TYPE_IVR, 0))
  50. {
  51. ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_ERROR, _T("{Network}: 连接CTI服务器[%s:%d]失败, 请检查端口[%d]是否被占用"), CtiIp, CtiPort, ListenPort);
  52. return false;
  53. }
  54. if (!CInterfaceWindow::getIocpLinkInstance()->CreatePduClient(CtiIp, CtiPort, PDU_DEV_TYPE_IVR, 0, PDU_DEV_TYPE_CTI, 0, true))
  55. {
  56. ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_ERROR, _T("{Network}: 连接CTI服务器[%s:%d]失败, 请检查网络配置是否正常"), CtiIp, CtiPort);
  57. return false;
  58. } // end if
  59. return TRUE;
  60. }
  61. /*****************************************************************
  62. **【函数名称】 release
  63. **【函数功能】 连接释放
  64. **【参数】
  65. **【返回值】
  66. ****************************************************************/
  67. void CNetworkIvr::release( void )
  68. {
  69. CInterfaceWindow::getLinkInstance()->StopAll();
  70. }
  71. /*****************************************************************
  72. **【函数名称】 Send
  73. **【函数功能】 发送消息
  74. **【参数】 设备类型,命令内容
  75. **【返回值】
  76. ****************************************************************/
  77. BOOL CNetworkIvr::send(CPduEntity& a_PduEntity)
  78. {
  79. if (!m_IsCtiConnected)
  80. return false;
  81. /*
  82. // 判断是返回消息还是主动给CTI的消息
  83. IPduComm* pComm = CInterfaceWindow::getCommInstance();
  84. if(a_PduEntity.GetIsExecReturn())
  85. return pComm->Send(&a_PduEntity, a_PduEntity.GetLocalDevType(), a_PduEntity.GetLocalDevId());
  86. return pComm->Send(&a_PduEntity, PDU_DEV_TYPE_CTI, m_CtiDevID);
  87. */
  88. // 判断是返回消息还是主动给CTI的消息 2022-10-26 改用iocp,保持和CTI,ACD一样
  89. auto pComm = CInterfaceWindow::getIocpCommInstance();
  90. if (a_PduEntity.GetIsExecReturn())
  91. pComm->Send(&a_PduEntity, a_PduEntity.GetLocalDevType(), a_PduEntity.GetLocalDevId());
  92. return pComm->Send(&a_PduEntity, PDU_DEV_TYPE_CTI, m_CtiDevID);
  93. }
  94. /*****************************************************************
  95. **【函数名称】 OnLinkStateChanged
  96. **【函数功能】 连接状态变化事件
  97. **【参数】 linkContent 连接信息
  98. **【返回值】
  99. ****************************************************************/
  100. void CNetworkIvr::OnLinkStateChanged( const PduLinkContent& linkContent )
  101. {
  102. CString Msg;
  103. LOG_LEVEL Level = LOG_LEVEL_NORMAL;
  104. switch(linkContent.nLinkState)
  105. {
  106. case PDU_LINK_STATE_SUCCESSED: // 请求连接成功
  107. Msg.Format(_T("Far End[Ip = %s, Port = %d], Hint = 网络连接成功..."),
  108. linkContent.szFarIp,
  109. linkContent.nFarPort);
  110. break;
  111. case PDU_LINK_STATE_FAILED: // 请求连接失败
  112. Msg.Format(_T("Far End[Ip = %s, Port = %d], Hint = 网络连接失败..."),
  113. linkContent.szFarIp,
  114. linkContent.nFarPort);
  115. Level = LOG_LEVEL_ERROR;
  116. break;
  117. case PDU_LINK_STATE_DISCONNECTED: // 连接已断开
  118. {
  119. Msg.Format(_T("Far End[Ip = %s, Port = %d], Hint = 网络连接已断开..."),
  120. linkContent.szFarIp,
  121. linkContent.nFarPort);
  122. m_IsCtiConnected = false;
  123. CIvrCore::GetInstance().onNetLinkUpdated(false);
  124. Level = LOG_LEVEL_ERROR;
  125. }
  126. break;
  127. case PDU_LINK_STATE_REG_OK: // 注册成功
  128. {
  129. Msg.Format(_T("Far End[Type = %d, Id = %d, Ip = %s, Port = %d], Hint = 网络连接注册成功..."),
  130. linkContent.nFarType,
  131. linkContent.nFarId,
  132. linkContent.szFarIp,
  133. linkContent.nFarPort);
  134. if (linkContent.nFarType == PDU_DEV_TYPE_CTI)
  135. {
  136. m_IsCtiConnected = true;
  137. m_CtiDevID = linkContent.nFarId;
  138. CIvrCore::GetInstance().onNetLinkUpdated(true);
  139. }
  140. }
  141. break;
  142. case PDU_LINK_STATE_REG_FAILED: // 注册失败
  143. Msg.Format(_T("Far End[Ip = %s, Port = %d], Hint = 网络连接注册失败, 通讯禁止..."),
  144. linkContent.szFarIp,
  145. linkContent.nFarPort);
  146. Level = LOG_LEVEL_ERROR;
  147. break;
  148. default:
  149. Msg.Format(_T("Far End[Type = %d, Id = %d, Ip = %s, Port = %d]"),
  150. linkContent.nFarType,
  151. linkContent.nFarId,
  152. linkContent.szFarIp,
  153. linkContent.nFarPort);
  154. break;
  155. } // end switch
  156. ILogger::getInstance().log(LOG_CLASS_SOCKET, Level, _T("%s"), Msg);
  157. }
  158. /*****************************************************************
  159. **【函数名称】 OnRecvCommand
  160. **【函数功能】 接收具体命令并进行处理
  161. **【参数】
  162. **【返回值】
  163. ****************************************************************/
  164. void CNetworkIvr::OnRecvCommand(CPduEntity* a_pPduEntity)
  165. {
  166. PDU_CMD_TYPE Type = a_pPduEntity->GetCmdType();
  167. if (Type != PDU_CMD_REG)
  168. CWarningPush::getInstance()->heartMonitor(a_pPduEntity->GetLocalDevType(), a_pPduEntity->GetPeerDevType());
  169. // 注册命令返回以及心跳包不处理
  170. if (Type == PDU_CMD_REG || Type == PDU_CMD_LISTEN)
  171. {
  172. return;
  173. }
  174. CPduEntity* pNewPdu = new CPduEntity(*a_pPduEntity);
  175. CMsgCenter::GetInstance().pushMsg(IVR_MSG_PDU_RECIVE, pNewPdu);
  176. }