中间件底层,websocket

NetworkCti.cpp 9.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. #include "StdAfx.h"
  2. #include "NetworkCti.h"
  3. #include "LineHolder.h"
  4. #include "IvrFlowHolder.h"
  5. #include "Logger.h"
  6. #include "MsgCenter.h"
  7. #include "Config.h"
  8. #include "CtiDataDef.h"
  9. #include "TaskMgr.h"
  10. SINGLETON_IMPLEMENT(CNetworkCti)
  11. CNetworkCti::CNetworkCti(void) : m_IsAcdConnected(FALSE), m_IsIvrConnected(FALSE)
  12. {
  13. }
  14. void CNetworkCti::__procRegDevListMsg(CPduEntity & a_PduEntity)
  15. {
  16. auto devList = a_PduEntity.GetDataString(0);
  17. CString dev;
  18. dev.Format("|%d|", PDU_DEV_TYPE_IVR);
  19. bool newIvrConnected = devList.Find(dev) < 0 ? false : true;
  20. dev.Format("|%d|", PDU_DEV_TYPE_ACD);
  21. auto newAcdConnected = devList.Find(dev) < 0 ? false : true;
  22. if (!m_IsAcdConnected && newAcdConnected) { // acd 连接
  23. // 通知线路类Acd连接成功
  24. CLineHolder::GetInstance().onAcdConnected();
  25. }
  26. else if (m_IsAcdConnected && !newAcdConnected) { // acd连接断开
  27. }
  28. m_IsAcdConnected = newAcdConnected;
  29. if (m_IsIvrConnected && !newIvrConnected) { // ivr掉线
  30. // 通知IvrFlow IVR连接断开
  31. CIvrFlowHolder::GetInstance().onIvrDisconnect();
  32. }
  33. else if (!m_IsIvrConnected && newIvrConnected) { // ivr上线
  34. }
  35. m_IsIvrConnected = newIvrConnected;
  36. }
  37. CNetworkCti::~CNetworkCti(void)
  38. {
  39. }
  40. /*****************************************************************
  41. **【函数名称】 __procRegMsg
  42. **【函数功能】 处理注册命令
  43. **【参数】 a_PduEntity:注册命令
  44. **【返回值】
  45. ****************************************************************/
  46. void CNetworkCti::__procRegMsg(CPduEntity& a_PduEntity)
  47. {
  48. bool RegResult = false;
  49. switch (a_PduEntity.GetLocalDevType())
  50. {
  51. case PDU_DEV_TYPE_ACD:
  52. RegResult = m_DevAcd.DevId == -1 ? true : false;
  53. break;
  54. case PDU_DEV_TYPE_IVR:
  55. RegResult = m_DevIvr.DevId == -1 ? true : false;
  56. break;
  57. default:
  58. ASSERT(FALSE);
  59. break;
  60. }
  61. // 发送注册结果
  62. a_PduEntity.SetToExecReturn();
  63. a_PduEntity.SetDataBool(0, RegResult);
  64. CNetInterface::getNetInstance()->Send(&a_PduEntity, a_PduEntity.GetLocalDevType(), a_PduEntity.GetLocalDevId());
  65. }
  66. /*****************************************************************
  67. **【函数名称】 __onRegSuccess
  68. **【函数功能】 设备注册成功处理函数
  69. **【参数】 linkContent:注册段信息
  70. **【返回值】
  71. ****************************************************************/
  72. void CNetworkCti::__onRegSuccess(const PduLinkContent& linkContent)
  73. {
  74. switch (linkContent.nFarType)
  75. {
  76. case PDU_DEV_TYPE_ACD:
  77. {
  78. // 保存设备信息
  79. m_DevAcd.DevId = linkContent.nLocalId;
  80. lstrcpy(m_DevAcd.szIpAddress, linkContent.szFarIp);
  81. m_DevAcd.Port = linkContent.nFarPort;
  82. m_IsAcdConnected = TRUE;
  83. // 通知线路类Acd连接成功
  84. CLineHolder::GetInstance().onAcdConnected();
  85. }
  86. break;
  87. case PDU_DEV_TYPE_IVR:
  88. {
  89. // 保存设备信息
  90. m_DevIvr.DevId = linkContent.nLocalId;
  91. lstrcpy(m_DevIvr.szIpAddress, linkContent.szFarIp);
  92. m_DevIvr.Port = linkContent.nFarPort;
  93. m_IsIvrConnected = TRUE;
  94. }
  95. break;
  96. default:
  97. ASSERT(FALSE);
  98. break;
  99. }
  100. }
  101. /*****************************************************************
  102. **【函数名称】 __onDisconnect
  103. **【函数功能】 设备连接断开处理函数
  104. **【参数】 linkContent:连接断开端信息
  105. **【返回值】
  106. ****************************************************************/
  107. void CNetworkCti::__onDisconnect(const PduLinkContent& linkContent)
  108. {
  109. switch (linkContent.nFarType)
  110. {
  111. case PDU_DEV_TYPE_ACD:
  112. {
  113. if (m_DevAcd.DevId != linkContent.nLocalId) return;
  114. if (strcmp(m_DevAcd.szIpAddress, linkContent.szFarIp) != 0) return;
  115. if (m_DevAcd.Port != linkContent.nFarPort) return;
  116. memset(&m_DevAcd, 0, sizeof(m_DevAcd));
  117. m_DevAcd.DevId = -1;
  118. m_IsAcdConnected = FALSE;
  119. }
  120. break;
  121. case PDU_DEV_TYPE_IVR:
  122. {
  123. if (m_DevIvr.DevId != linkContent.nLocalId) return;
  124. if (strcmp(m_DevIvr.szIpAddress, linkContent.szFarIp) != 0) return;
  125. if (m_DevIvr.Port != linkContent.nFarPort) return;
  126. memset(&m_DevIvr, 0, sizeof(m_DevIvr));
  127. m_DevIvr.DevId = -1;
  128. // 通知IvrFlow IVR连接断开
  129. CIvrFlowHolder::GetInstance().onIvrDisconnect();
  130. m_IsIvrConnected = FALSE;
  131. }
  132. break;
  133. default:
  134. break;
  135. }
  136. }
  137. void CNetworkCti::__onHeartMonitorDrop(int devType)
  138. {
  139. }
  140. /*****************************************************************
  141. **【函数名称】 OnLinkStateChanged
  142. **【函数功能】 连接状态信息变化
  143. **【参数】
  144. **【返回值】
  145. ****************************************************************/
  146. void CNetworkCti::OnLinkStateChanged(const PduLinkContent& linkContent)
  147. {
  148. // 连接信息日志显示
  149. LOG_LEVEL nLogLevel = LOG_LEVEL_WARNING;
  150. CString Msg;
  151. switch (linkContent.nLinkState)
  152. {
  153. case PDU_LINK_STATE_SUCCESSED:
  154. break;
  155. case PDU_LINK_STATE_FAILED:
  156. break;
  157. case PDU_LINK_STATE_DISCONNECTED:
  158. {
  159. Msg = _T("{Net}: Far End Disconnected, ");
  160. nLogLevel = LOG_LEVEL_WARNING;
  161. __onDisconnect(linkContent);
  162. }
  163. break;
  164. case PDU_LINK_STATE_REG_OK:
  165. {
  166. Msg = _T("{Net}: Far End Reg OK, ");
  167. nLogLevel = LOG_LEVEL_NORMAL;
  168. __onRegSuccess(linkContent);
  169. }
  170. break;
  171. case PDU_LINK_STATE_REG_FAILED:
  172. {
  173. Msg = _T("{Net}: Far End Reg Failed, ");
  174. nLogLevel = LOG_LEVEL_WARNING;
  175. }
  176. break;
  177. default:
  178. {
  179. Msg = _T("{Net}: Unknown Netlink State, ");
  180. nLogLevel = LOG_LEVEL_WARNING;
  181. }
  182. break;
  183. }
  184. // 通知日志
  185. ILogger::getInstance().log(LOG_CLASS_SOCKET, nLogLevel, _T("%s"), Msg);
  186. }
  187. /*****************************************************************
  188. **【函数名称】 OnRecvCommand
  189. **【函数功能】 Pdu命令处理接口
  190. **【参数】 a_pPduEntity:消息实体
  191. **【返回值】
  192. ****************************************************************/
  193. void CNetworkCti::OnRecvCommand(CPduEntity* a_pPduEntity)
  194. {
  195. ASSERT(a_pPduEntity != NULL);
  196. if (a_pPduEntity->GetCmdType() != PDU_CMD_LISTEN) // 心跳命令不打印
  197. {
  198. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, _T("{CNetworkCti}:OnRecvCommand,CmdType=%d,LocalDevType[%d]"), a_pPduEntity->GetCmdType(), a_pPduEntity->GetLocalDevType());
  199. }
  200. CWarningPush::getInstance()->heartMonitor(a_pPduEntity->GetLocalDevType(), a_pPduEntity->GetPeerDevType());
  201. switch (a_pPduEntity->GetCmdType())
  202. {
  203. case PDU_CMD_REG: // 注册命令
  204. __procRegMsg(*a_pPduEntity);
  205. break;
  206. case PDU_CMD_DEV_ONLINE_LIST: // 设备在线列表
  207. __procRegDevListMsg(*a_pPduEntity);
  208. break;
  209. case PDU_CMD_CTI_IVR_CALLIN: // CallIn返回命令
  210. case PDU_CMD_CTI_IVR_TURNIVR: // 转IVR返回命令
  211. case PDU_CMD_IVR_HANGUP: // IVR通知CTI挂机
  212. case PDU_CMD_IVR_END: // IVR通知CTI流程结束
  213. case PDU_CMD_IVR_WANT_AGENT: // IVR通知CTI请求排队(包括ACD返回)
  214. case PDU_CMD_IVR_QUEUE_CONTINUE: // IVR通知CTI继续排队(包括ACD返回)
  215. case PDU_CMD_IVR_QUEUE_CANCEL: // IVR通知CTI取消排队
  216. case PDU_CMD_IVR_TURN_AGENT: // IVR通知CTI转坐席
  217. case PDU_CMD_IVR_PLAY_DTMF: // IVR通知CTI放音收按键
  218. case PDU_CMD_IVR_CALL_OUT: // IVR通知CTI自动呼叫某个号码
  219. case PDU_CMD_IVR_TURN_OUTLINE: // IVR呼叫转移
  220. case PDU_CMD_IVR_FAX: // IVR通知收发传真
  221. case PDU_CMD_IVR_LEAVE_WORD: // IVR通知留言
  222. CIvrFlowHolder::GetInstance().onPduMessage(*a_pPduEntity);
  223. break;
  224. case PDU_CMD_LISTEN:
  225. return;
  226. case PDU_CMD_IVR_WAITER_COUNT: //2019 - 9 - 6 配合4.0acd返回排队人数
  227. {
  228. send2ACD(*a_pPduEntity); //发送至ACD
  229. int WaiterCount = a_pPduEntity->GetDataUInt(0);
  230. // m_WaiterCount.onWaiterCount(WaiterCount);
  231. ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL, "{NetWorkCti}:收到排队数量%d", WaiterCount);
  232. }
  233. break;
  234. default:
  235. {
  236. __try {
  237. CTaskMgr::GetInstance().onPduMessage(*a_pPduEntity);
  238. }
  239. __except (EXCEPTION_EXECUTE_HANDLER)
  240. {
  241. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{CNetworkCti}:OnRecvCommand,CTaskMgr异常,CmdType=%d,mdw5.1.19.1"), a_pPduEntity->GetCmdType());
  242. }
  243. break;
  244. }
  245. break;
  246. }
  247. }
  248. /*****************************************************************
  249. **【函数名称】 init
  250. **【函数功能】 初始化
  251. **【参数】
  252. **【返回值】 成功TRUE,失败FALSE
  253. ****************************************************************/
  254. BOOL CNetworkCti::init()
  255. {
  256. // 初始化客户端设备信息
  257. memset(&m_DevAcd, 0, sizeof(m_DevAcd));
  258. memset(&m_DevIvr, 0, sizeof(m_DevIvr));
  259. m_DevAcd.DevId = -1;
  260. m_DevIvr.DevId = -1;
  261. auto pClient = CNetInterface::getNetInstance();
  262. pClient->setLinkStateChanged(std::bind(&CNetworkCti::OnLinkStateChanged, this, std::placeholders::_1));
  263. pClient->setRecvCommand(std::bind(&CNetworkCti::OnRecvCommand, this, std::placeholders::_1));
  264. //2022-08-10 添加设备监听掉线回调, 监听acd,ivr是否掉线
  265. CWarningPush::getInstance()->setHeartDropFuncCB(std::bind(&CNetworkCti::__onHeartMonitorDrop, this, std::placeholders::_1));
  266. //连接ws服务器端
  267. CString Ip = CConfig::GetInstance().wsIP();
  268. int Port = CConfig::GetInstance().wsPort();
  269. if(pClient->CreatePduClient(Ip, Port, PDU_DEV_TYPE_CTI, 1, true))
  270. {
  271. ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL, "{Net}: 连接ws服务端成功,IP=%s,ListenPort = %d", Ip,Port);
  272. return TRUE;
  273. }
  274. else
  275. {
  276. ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_ERROR, "{Net}: 连接ws服务端失败,IP=%s,ListenPort = %d", Ip, Port);
  277. return FALSE;
  278. }
  279. return TRUE;
  280. }
  281. /*****************************************************************
  282. **【函数名称】 release
  283. **【函数功能】 释放资源
  284. **【参数】
  285. **【返回值】 成功TRUE,失败FALSE
  286. ****************************************************************/
  287. void CNetworkCti::release(void)
  288. {
  289. CNetInterface::getNetInstance()->ClosePduClient(PDU_DEV_TYPE_CTI, 1);
  290. }
  291. /*****************************************************************
  292. **【函数名称】 send2ACD
  293. **【函数功能】 发送PDU到ACD
  294. **【参数】 a_PduEntity:待发送的PDU
  295. **【返回值】
  296. ****************************************************************/
  297. BOOL CNetworkCti::send2ACD(CPduEntity& a_PduEntity)
  298. {
  299. return CNetInterface::getNetInstance()->Send(&a_PduEntity, PDU_DEV_TYPE_ACD, m_DevAcd.DevId);
  300. }
  301. /*****************************************************************
  302. **【函数名称】 send2IVR
  303. **【函数功能】 发送PDU到IVR
  304. **【参数】 a_PduEntity:待发送的PDU
  305. **【返回值】
  306. ****************************************************************/
  307. BOOL CNetworkCti::send2IVR(CPduEntity& a_PduEntity)
  308. {
  309. return CNetInterface::getNetInstance()->Send(&a_PduEntity, PDU_DEV_TYPE_IVR, m_DevIvr.DevId);
  310. }