中间件底层,websocket

IvrCore.cpp 9.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. #include "StdAfx.h"
  2. #include "IvrCore.h"
  3. #include "FlowTemplate.h"
  4. #include "IvrFlow.h"
  5. #include "NetworkIvr.h"
  6. #include "Config.h"
  7. #include "../Public/Auth/AuthMgr.h"
  8. #include "../Public/DaemonClient/DaemonClient.h"
  9. #include "MsgCenter.h"
  10. SINGLETON_IMPLEMENT(CIvrCore)
  11. void CIvrCore::onMessage(UINT MsgType, const PARAM lpContent)
  12. {
  13. if (MsgType == IVR_MSG_PDU_RECIVE)
  14. {
  15. CPduEntity* a_pPduEntity = (CPduEntity*)lpContent;
  16. if (a_pPduEntity != NULL)
  17. {
  18. procPdu(a_pPduEntity);
  19. }
  20. }
  21. }
  22. CIvrCore::CIvrCore(void)
  23. {
  24. }
  25. CIvrCore::~CIvrCore(void)
  26. {
  27. }
  28. /*****************************************************************
  29. **【函数名称】 __setupFlowEnvironment
  30. **【函数功能】 设置流程环境
  31. **【参数】
  32. **【返回值】 TRUE:解析成功,FALSE:解析失败
  33. ****************************************************************/
  34. bool CIvrCore::__setupFlowEnvironment( void )
  35. {
  36. bool Res = true;
  37. IOtlConnection* pDbControl = IOtlConnection::getInstance();
  38. IOtlRecordset *pRecordset = pDbControl->QueryRecords(_T("SELECT * FROM conf_ivr_flow"));
  39. if(NULL != pRecordset)
  40. {
  41. while(!pRecordset->IsEOF())
  42. {
  43. pRecordset->MoveNextRow();
  44. // 读取流程文件信息
  45. CString FileName = pRecordset->GetValueStr(_T("FilePath"));
  46. Res &= m_TemplateMgr.parseIvrFile(FileName);
  47. } // end while
  48. }
  49. m_FlowMgr.createFlow();
  50. IOtlRecordset::DestroyInstance(pRecordset);
  51. return Res;
  52. }
  53. /*****************************************************************
  54. **【函数名称】 __procMsgCtiCallIn
  55. **【函数功能】 处理CTI发过来的外线呼入消息
  56. **【参数】 pPduEntity:外线呼入消息
  57. **【返回值】
  58. ****************************************************************/
  59. void CIvrCore::__procMsgCtiCallIn( CPduEntity* pPduEntity )
  60. {
  61. pPduEntity->SetToExecReturn();
  62. CFlowTemplate *pTemplate = m_TemplateMgr.getTemplate(pPduEntity->GetDataUInt(5)); // 通过线路号查找关联流程模板
  63. if(pTemplate == NULL)
  64. pTemplate = m_TemplateMgr.getTemplate(pPduEntity->GetDataString(4)); // 根据被叫号码查找关联流程模板
  65. if(pTemplate != NULL)
  66. {
  67. CIvrFlow *pFlow = m_FlowMgr.getFreeFlow();
  68. if(pFlow != NULL)
  69. {
  70. pFlow->setFlowInfo(pPduEntity->GetDataULong(2), pPduEntity->GetDataUInt(5), pPduEntity->GetDataString(3), pPduEntity->GetDataString(4), pPduEntity->GetDataString(6));
  71. pPduEntity->SetDataBool(0, TRUE);
  72. pPduEntity->SetDataInt(1, pFlow->id());
  73. CNetworkIvr::GetInstance().send(*pPduEntity);
  74. pFlow->start(pTemplate);
  75. return;
  76. }
  77. else
  78. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Core}: 处理外线来电时无空闲流程, Caller = %s"), pPduEntity->GetDataString(3));
  79. }
  80. else
  81. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Core}: 处理外线来电时找不到关联流程模板, Caller = %s"), pPduEntity->GetDataString(3));
  82. pPduEntity->SetDataBool(0, FALSE);
  83. CNetworkIvr::GetInstance().send(*pPduEntity);
  84. }
  85. /*****************************************************************
  86. **【函数名称】 __procMsgCtiPredictiveCall
  87. **【函数功能】 处理CTI发过来的预测外呼消息
  88. **【参数】 pPduEntity:外线呼入消息
  89. **【返回值】
  90. ****************************************************************/
  91. void CIvrCore::__procMsgCtiPredictiveCall( CPduEntity* pPduEntity )
  92. {
  93. pPduEntity->SetToExecReturn();
  94. CFlowTemplate *pTemplate = m_TemplateMgr.getPreCallTemplate();
  95. ASSERT(pTemplate != NULL);
  96. if(pTemplate != NULL)
  97. {
  98. CIvrFlow *pFlow = m_FlowMgr.getFreeFlow();
  99. if(pFlow != NULL)
  100. {
  101. pFlow->setFlowInfo(pPduEntity->GetDataULong(2), pPduEntity->GetDataUInt(5), pPduEntity->GetDataInt(6),
  102. pPduEntity->GetDataUInt(7), pPduEntity->GetDataString(3), pPduEntity->GetDataString(4));
  103. pPduEntity->SetDataBool(0, TRUE);
  104. pPduEntity->SetDataInt(1, pFlow->id());
  105. CNetworkIvr::GetInstance().send(*pPduEntity);
  106. pFlow->start(pTemplate);
  107. return;
  108. }
  109. else
  110. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Core}: 处理预测外呼时无空闲流程, Callee = %s"), pPduEntity->GetDataString(4));
  111. }
  112. else
  113. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Core}: 处理预测外呼时找不到关联流程模板, Callee = %s"), pPduEntity->GetDataString(4));
  114. pPduEntity->SetDataBool(0, FALSE);
  115. CNetworkIvr::GetInstance().send(*pPduEntity);
  116. }
  117. /*****************************************************************
  118. **【函数名称】 __procMsgCtiTurnIvr
  119. **【函数功能】 处理CTI发来的坐席转IVR消息
  120. **【参数】 pPduEntity:坐席转IVR命令
  121. **【返回值】
  122. ****************************************************************/
  123. void CIvrCore::__procMsgCtiTurnIvr( CPduEntity* pPduEntity )
  124. {
  125. pPduEntity->SetToExecReturn();
  126. CFlowTemplate* pTemplate = m_TemplateMgr.findTemplate(pPduEntity->GetDataString(8));
  127. if(pTemplate != NULL)
  128. {
  129. CIvrFlow *pFlow = m_FlowMgr.getFreeFlow();
  130. if(pFlow != NULL)
  131. {
  132. // 设置系统变量
  133. pFlow->setFlowInfo(pPduEntity->GetDataULong(2), pPduEntity->GetDataUInt(5), pPduEntity->GetDataString(3), pPduEntity->GetDataString(4));
  134. // 设置随路数据变量
  135. pFlow->setFlowAssoData(pPduEntity->GetDataString(9));
  136. pPduEntity->SetDataBool(0, TRUE);
  137. pPduEntity->SetDataInt(1, pFlow->id());
  138. CNetworkIvr::GetInstance().send(*pPduEntity);
  139. pFlow->start(pTemplate);
  140. return;
  141. }
  142. else
  143. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Core}: 处理跳转IVR时无空闲流程"));
  144. }
  145. else
  146. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Core}: 处理跳转IVR时找不到目标流程模板"));
  147. pPduEntity->SetDataBool(0,FALSE);
  148. CNetworkIvr::GetInstance().send(*pPduEntity);
  149. }
  150. /*****************************************************************
  151. **【函数名称】 __procMsgCtiHangup
  152. **【函数功能】 处理CTI发来的外线挂机消息
  153. **【参数】 pPduEntity:Pdu命令
  154. **【返回值】
  155. ****************************************************************/
  156. void CIvrCore::__procMsgCtiHangup( CPduEntity* pPduEntity )
  157. {
  158. int FlowId = pPduEntity->GetDataInt(1);
  159. CIvrFlow *pFlow = m_FlowMgr.getFlow(FlowId);
  160. if(pFlow != NULL && pFlow->state() == IVR_FLOW_STATE_RUN)
  161. pFlow->procPdu(pPduEntity);
  162. else
  163. ILogger::getInstance().log(LOG_CLASS_SOCKET,LOG_LEVEL_WARNING,_T("{Core}: 收到外线挂机消息, 但关联流程线路[%d]已释放"), FlowId);
  164. }
  165. /*****************************************************************
  166. **【函数名称】 stage1Start
  167. **【函数功能】 第一阶段启动
  168. **【参数】
  169. **【返回值】
  170. ****************************************************************/
  171. bool CIvrCore::stage1Start( void )
  172. {
  173. // 连接配置数据库
  174. if(!IOtlConnection::getInstance()->Connect())
  175. {
  176. AfxMessageBox(STR_ERR_CORE_INIT_DB);
  177. return false;
  178. }
  179. // 加载配置
  180. if(!CConfig::load())
  181. {
  182. IOtlConnection::getInstance()->Disconnect();
  183. AfxMessageBox(STR_ERR_CORE_INIT_CFG);
  184. return false;
  185. }
  186. return true;
  187. }
  188. /*****************************************************************
  189. **【函数名称】 stage2Start
  190. **【函数功能】 第一阶段启动
  191. **【参数】 ErrInfo: 出错信息
  192. **【返回值】
  193. ****************************************************************/
  194. bool CIvrCore::stage2Start( void )
  195. {
  196. // 2022-05-10 pdu消息通过msgcenter异步处理
  197. CMsgCenter::GetInstance().regist(IVR_MSG_PDU_RECIVE, this);
  198. // 建立网络通讯
  199. if(!CNetworkIvr::GetInstance().init())
  200. {
  201. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_ERROR, _T("%s"), STR_ERR_CORE_INIT_NETWORK);
  202. return false;
  203. }
  204. // #ifndef _DEBUG
  205. // CAuthMgr::GetInstance().init();
  206. // #endif
  207. if(!__setupFlowEnvironment())
  208. {
  209. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_ERROR, _T("%s"), STR_ERR_CORE_INIT_FLOW);
  210. return false;
  211. }
  212. // 启动自动流程
  213. m_TemplateMgr.execAutoFlowTemplate(m_FlowMgr);
  214. CDaemonClient::GetInstance().doWork();
  215. return true;
  216. }
  217. /*****************************************************************
  218. **【函数名称】 exit
  219. **【函数功能】 退出IVR
  220. **【参数】
  221. **【返回值】
  222. ****************************************************************/
  223. void CIvrCore::exit( void )
  224. {
  225. CNetworkIvr::GetInstance().release();
  226. IOtlConnection::getInstance()->Disconnect();
  227. }
  228. /*****************************************************************
  229. **【函数名称】 procPdu
  230. **【函数功能】 处理CTI发过来的PDU消息
  231. **【参数】 a_pPduEntity:PDU消息
  232. **【返回值】
  233. ****************************************************************/
  234. void CIvrCore::procPdu( CPduEntity* pPduEntity )
  235. {
  236. // 返回命令的处理
  237. if(pPduEntity->GetIsExecReturn())
  238. {
  239. if(pPduEntity->GetCmdType() == PDU_CMD_IVR_HANGUP)
  240. return;
  241. CIvrFlow *pFlow = m_FlowMgr.getFlow(pPduEntity->GetDataInt(1));
  242. if(pFlow != NULL)
  243. {
  244. ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL, _T("CTI -> IVR, CMD = Return[%d], IVR = %d, 执行结果 = %d"),
  245. pPduEntity->GetCmdType(),
  246. pPduEntity->GetDataInt(1),
  247. pPduEntity->GetDataBool(0));
  248. pFlow->procPdu(pPduEntity);
  249. }
  250. else
  251. {
  252. ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_WARNING,_T("CTI -> IVR, CMD = Return[%d], IVR = %d, 执行结果 = %d, IVR线路已释放"),
  253. pPduEntity->GetCmdType(),
  254. pPduEntity->GetDataInt(1),
  255. pPduEntity->GetDataBool(0));
  256. }
  257. }
  258. else
  259. {
  260. switch(pPduEntity->GetCmdType())
  261. {
  262. case PDU_CMD_CTI_IVR_CALLIN: // CTI通知IVR外线来电
  263. __procMsgCtiCallIn(pPduEntity);
  264. break;
  265. case PDU_CMD_CTI_IVR_PREDICTIVECALL: // CTI通知IVR预测外呼
  266. __procMsgCtiPredictiveCall(pPduEntity);
  267. break;
  268. case PDU_CMD_CTI_IVR_TURNIVR: // CTI通知IVR转IVR
  269. __procMsgCtiTurnIvr(pPduEntity);
  270. break;
  271. case PDU_CMD_CTI_IVR_HANGUP: // CTI通知IVR外线挂机
  272. __procMsgCtiHangup(pPduEntity);
  273. break;
  274. default:
  275. break;
  276. } // end switch
  277. }
  278. }
  279. /*****************************************************************
  280. **【函数名称】 onNetLinkUpdated
  281. **【函数功能】 响应网络连接成功或断开事件
  282. **【参数】 IsConnect:网络连接成功或断开
  283. **【返回值】
  284. ****************************************************************/
  285. void CIvrCore::onNetLinkUpdated( bool IsConnect )
  286. {
  287. m_FlowMgr.onNetLinkUpdated(IsConnect);
  288. }