中间件底层,websocket

TaskMgr.cpp 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522
  1. #include "StdAfx.h"
  2. #include "TaskMgr.h"
  3. #include "TaskInc.h"
  4. #include "CtiCore.h"
  5. #include "MsgCenter.h"
  6. #include "LineHolder.h"
  7. #include "LogicLine.h"
  8. SINGLETON_IMPLEMENT(CTaskMgr)
  9. CTaskMgr::CTaskMgr(void)
  10. {
  11. }
  12. CTaskMgr::~CTaskMgr(void)
  13. {
  14. }
  15. /*****************************************************************
  16. **【函数名称】 __addTask
  17. **【函数功能】 添加Task
  18. **【参数】
  19. **【返回值】
  20. ****************************************************************/
  21. void CTaskMgr::__addTask( CTask* pTask )
  22. {
  23. m_TaskLock.Lock();
  24. m_TaskTable.SetAt(reinterpret_cast<LONG>(pTask), pTask);
  25. m_TaskLock.Unlock();
  26. }
  27. /*****************************************************************
  28. **【函数名称】 __onAgentLogin
  29. **【函数功能】 坐席签入处理
  30. **【参数】 消息实体
  31. **【返回值】
  32. ****************************************************************/
  33. void CTaskMgr::__onAgentLogin( CPduEntity &PduEntity )
  34. {
  35. // 显示日志
  36. ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL, _T("Agent->CTI, CMD = [坐席签入], \
  37. Exten = %d, Agent = %d"),
  38. PduEntity.GetDataUInt(1),
  39. PduEntity.GetDataUInt(2));
  40. // 设置内线分机的当前坐席工号
  41. CLogicLine* pLine = CLineHolder::GetInstance().getLogicLine(PduEntity.GetDataUInt(1));
  42. if(pLine == NULL)
  43. ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_WARNING, _T("{TaskMgr}: 坐席[%d]签入绑定分机失败: 无法获取目标分机[%d]"), PduEntity.GetDataUInt(2),
  44. PduEntity.GetDataUInt(1));
  45. else
  46. pLine->setAgentNum(PduEntity.GetDataUInt(2), PduEntity.GetDataString(3));
  47. }
  48. /*****************************************************************
  49. **【函数名称】 __onAgentLogout
  50. **【函数功能】 坐席签出处理
  51. **【参数】 消息实体
  52. **【返回值】
  53. ****************************************************************/
  54. void CTaskMgr::__onAgentLogout( CPduEntity &PduEntity )
  55. {
  56. // 显示日志
  57. ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL, _T("Agent->CTI, CMD = [坐席签出], Exten = %d, Agent = %d"),
  58. PduEntity.GetDataUInt(1),
  59. PduEntity.GetDataUInt(2));
  60. // 设置内线分机的当前坐席工号
  61. CLogicLine* pLine = CLineHolder::GetInstance().getLogicLine(PduEntity.GetDataUInt(1));
  62. if(pLine != NULL)
  63. pLine->setAgentNum(0,"");
  64. }
  65. /*****************************************************************
  66. **【函数名称】 __onAgentReset
  67. **【函数功能】 重置处理
  68. **【参数】 消息实体
  69. **【返回值】
  70. ****************************************************************/
  71. void CTaskMgr::__onAgentReset( CPduEntity &PduEntity )
  72. {
  73. // 显示日志
  74. ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL, _T("Agent->CTI, CMD = [坐席重置], Exten = %d"), PduEntity.GetDataUInt(1));
  75. // 获取线路类指针
  76. CLogicLine* pLine = CLineHolder::GetInstance().getLogicLine(PduEntity.GetDataUInt(1));
  77. if(pLine == NULL)
  78. return;
  79. // 删除关联任务
  80. removeTask(pLine->taskIdBinded());
  81. // 物理重置
  82. CCtiCore::GetInstance().getDevLink().exec(-1, LINE_OP_RESET, pLine->lineId(), NULL);
  83. }
  84. /*****************************************************************
  85. **【函数名称】 __onTaskFailed
  86. **【函数功能】 处理Task执行失败
  87. **【参数】 消息实体
  88. **【返回值】
  89. ****************************************************************/
  90. void CTaskMgr::__onTaskFailed( CTask* pTask, CPduEntity &PduEntity )
  91. {
  92. // 显示日志
  93. CString DevType;
  94. UINT HostLine;
  95. if(PduEntity.GetLocalDevType() == PDU_DEV_TYPE_ACD)
  96. {
  97. DevType = _T("ACD");
  98. HostLine = PduEntity.GetDataUInt(1);
  99. }
  100. else
  101. {
  102. DevType = _T("IVR");
  103. HostLine = PduEntity.GetDataUInt(3);
  104. }
  105. ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_WARNING, _T("CTI->%s, CMD[%d]执行失败, Line = %d"), DevType, PduEntity.GetCmdType(), HostLine);
  106. // 命令返回
  107. PduEntity.SetToExecReturn();
  108. PduEntity.SetDataBool(0, false);
  109. CNetInterface::getNetInstance()->Send(&PduEntity, PduEntity.GetLocalDevType(), PduEntity.GetLocalDevId());
  110. // 移除Task
  111. removeTask(reinterpret_cast<LONG>(pTask));
  112. }
  113. /*****************************************************************
  114. **【函数名称】 __procDevOpProcess
  115. **【函数功能】 处理设备操作进展
  116. **【参数】 EvtType 消息事件类型
  117. lpContent 消息内容
  118. **【返回值】
  119. ****************************************************************/
  120. void CTaskMgr::__procDevOpProcess( UINT EvtType, const PARAM lpContent )
  121. {
  122. EventOpProcess &EvtInfo = *(EventOpProcess*)lpContent;
  123. // 查找到Task并处理
  124. CTask* pTask = findTask(EvtInfo.nInstance);
  125. if(pTask != NULL)
  126. pTask->OnDevOpProcess(EvtInfo);
  127. }
  128. /*****************************************************************
  129. **【函数名称】 __procDevOpResult
  130. **【函数功能】 设备操作结果返回
  131. **【参数】 EvtType 消息事件类型
  132. lpContent 消息内容
  133. **【返回值】
  134. ****************************************************************/
  135. void CTaskMgr::__procDevOpResult( UINT EvtType, const PARAM lpContent )
  136. {
  137. __try
  138. {
  139. EventOpResult &EvtInfo = *(EventOpResult*)lpContent;
  140. // 查找到Task并处理
  141. CTask* pTask = findTask(EvtInfo.nInstance);
  142. if (pTask != NULL)
  143. {
  144. // 返回True代表处理完成,移除Task
  145. if (pTask->OnDevOpResult(EvtInfo))
  146. removeTask(EvtInfo.nInstance);
  147. }
  148. }
  149. __except (EXCEPTION_EXECUTE_HANDLER)
  150. {
  151. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_ERROR, _T("{TaskMgr}: Task-异常__procDevOpResult"));
  152. }
  153. }
  154. /*****************************************************************
  155. **【函数名称】 __procDevOperator
  156. **【函数功能】 设备主动操作
  157. **【参数】 EvtType 消息事件类型
  158. lpContent 消息内容
  159. **【返回值】
  160. ****************************************************************/
  161. void CTaskMgr::__procDevOperator( UINT EvtType, const PARAM lpContent )
  162. {
  163. CTask *pTask = NULL;
  164. // 事件内容解析
  165. EventDevOperation &EvtInfo = *(EventDevOperation*)lpContent;
  166. switch(EvtInfo.nOpType)
  167. {
  168. case DEV_OP_CALL_IN: // 外线来电
  169. pTask = new(std::nothrow) CTaskDevCallIn(EvtInfo);
  170. break;
  171. case DEV_OP_CALL_OUT: // 物理外呼
  172. pTask = new(std::nothrow) CTaskDevCall(EvtInfo);
  173. break;
  174. default:
  175. break;
  176. }
  177. if(pTask == NULL)
  178. return;
  179. // 保存Task
  180. __addTask(pTask);
  181. // 返回Fals代表执行失败,移除Task
  182. if(!pTask->DoTask())
  183. removeTask((long)pTask);
  184. }
  185. /*****************************************************************
  186. **【函数名称】 init
  187. **【函数功能】 模块初始化
  188. **【参数】
  189. **【返回值】
  190. ****************************************************************/
  191. void CTaskMgr::init( void )
  192. {
  193. // 注册底层设备消息和设备操作结果
  194. CMsgCenter& MC = CMsgCenter::GetInstance();
  195. MC.regist(DEV_EVENT_DEV_OPERATOR, this);
  196. MC.regist(DEV_EVENT_LINE_OP_PROCESS, this);
  197. MC.regist(DEV_EVENT_LINE_OP_RESULT, this);
  198. }
  199. void CTaskMgr::uninit(void)
  200. {
  201. // 注册底层设备消息和设备操作结果
  202. CMsgCenter& MC = CMsgCenter::GetInstance();
  203. MC.unregist(DEV_EVENT_DEV_OPERATOR, this);
  204. MC.unregist(DEV_EVENT_LINE_OP_PROCESS, this);
  205. MC.unregist(DEV_EVENT_LINE_OP_RESULT, this);
  206. }
  207. /*****************************************************************
  208. **【函数名称】 removeTask
  209. **【函数功能】 删除Task
  210. **【参数】
  211. **【返回值】
  212. ****************************************************************/
  213. void CTaskMgr::removeTask( long TaskId )
  214. {
  215. if(TaskId == TASK_ID_INVALID)
  216. return;
  217. m_TaskLock.Lock();
  218. CTask* pTask = NULL;
  219. if(m_TaskTable.Lookup(TaskId, pTask))
  220. {
  221. m_TaskTable.RemoveKey(TaskId);
  222. // 删除Task
  223. ASSERT(pTask != NULL);
  224. delete pTask;
  225. pTask=NULL;
  226. }
  227. POSITION pos = m_TaskTable.GetStartPosition();
  228. LONG strKey = 0;
  229. while (pos) {
  230. m_TaskTable.GetNextAssoc(pos, strKey, pTask);
  231. if (pTask == NULL || pTask->IsExpire()) {
  232. m_TaskTable.RemoveKey(strKey);
  233. if (pTask != NULL) {
  234. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_ERROR, _T("{TaskMgr}: 失效Task[%s]TaskId[%ld]LineId[%d]时间[%ld]删除"),pTask->Name(), reinterpret_cast<LONG>(pTask),pTask->GetAssoLineId(),pTask->TaskTime());
  235. delete pTask;
  236. pTask = NULL;
  237. }
  238. else {
  239. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_ERROR, _T("{TaskMgr}: 失效Task删除"));
  240. }
  241. }
  242. }
  243. m_TaskLock.Unlock();
  244. }
  245. /*****************************************************************
  246. **【函数名称】 findTask
  247. **【函数功能】 查找Task
  248. **【参数】
  249. **【返回值】
  250. ****************************************************************/
  251. CTask* CTaskMgr::findTask( long TaskId )
  252. {
  253. if(TaskId == TASK_ID_INVALID)
  254. return NULL;
  255. CTask* pTask = NULL;
  256. m_TaskLock.Lock();
  257. m_TaskTable.Lookup(TaskId, pTask);
  258. m_TaskLock.Unlock();
  259. return pTask;
  260. }
  261. /*****************************************************************
  262. **【函数名称】 onPduMessage
  263. **【函数功能】 Pdu命令处理接口
  264. **【参数】 PduEntity: 消息实体
  265. **【返回值】
  266. ***************************************************************/
  267. void CTaskMgr::onPduMessage( CPduEntity &PduEntity )
  268. {
  269. // 根据命令类型创建Task
  270. CTask *pTask = NULL;
  271. PDU_CMD_TYPE nCmdType = PduEntity.GetCmdType();
  272. switch(nCmdType)
  273. {
  274. case PDU_CMD_AGENT_LOGIN: // 坐席签入
  275. __onAgentLogin(PduEntity);
  276. break;
  277. case PDU_CMD_AGENT_LOGOUT: // 坐席签出
  278. __onAgentLogout(PduEntity);
  279. break;
  280. case PDU_CMD_AGENT_MAKECALL: // 坐席外呼
  281. pTask = new(std::nothrow) CTaskAgentCall(PduEntity);
  282. break;
  283. case PDU_CMD_AGENT_ANSWER: // 坐席应答
  284. pTask = new(std::nothrow) CTaskAgentAnswer(PduEntity);
  285. break;
  286. case PDU_CMD_AGENT_HANGUP: // 坐席挂机
  287. pTask = new(std::nothrow) CTaskAgentHungUp(PduEntity);
  288. break;
  289. case PDU_CMD_AGENT_CANCEL: // 坐席取消操作
  290. pTask = new(std::nothrow) CTaskAgentCancel(PduEntity);
  291. break;
  292. case PDU_CMD_AGENT_RESET: // 坐席重置
  293. __onAgentReset(PduEntity);
  294. break;
  295. case PDU_CMD_AGENT_HOLD: // 坐席保持
  296. pTask = new(std::nothrow) CTaskAgentHold(PduEntity);
  297. break;
  298. case PDU_CMD_AGENT_TAKEBACK: // 坐席接回
  299. pTask = new(std::nothrow) CTaskAgentTakeBack(PduEntity);
  300. break;
  301. case PDU_CMD_AGENT_TRANSTALK: // 坐席转移
  302. pTask = new(std::nothrow) CTaskAgentTransfer(PduEntity);
  303. break;
  304. case PDU_CMD_AGENT_THREETALK: // 坐席三方
  305. pTask = new(std::nothrow) CTaskAgentThreeTalk(PduEntity);
  306. break;
  307. case PDU_CMD_AGENT_THREETALK_TAKEBACK: // 坐席三方接回主叫
  308. pTask = new(std::nothrow) CTaskAgentThreeTalkTakeBack(PduEntity);
  309. break;
  310. case PDU_CMD_AGENT_CONSULTATION_CALL:// 协商呼叫
  311. pTask = new(std::nothrow) CTaskAgentConsulCall(PduEntity);
  312. break;
  313. case PDU_CMD_AGENT_CONFIRM_TRANSFER:// 确认转移
  314. onTaskPduMsg(PduEntity.GetDataUInt(1), PduEntity);
  315. break;
  316. case PDU_CMD_AGENT_MONI_LISTEN: // 监听
  317. pTask = new(std::nothrow) CTaskMonitorListen(PduEntity);
  318. break;
  319. case PDU_CMD_AGENT_MONI_REPLACE: // 代接
  320. pTask = new(std::nothrow) CTaskMonitorInstead(PduEntity);
  321. break;
  322. case PDU_CMD_AGENT_MONI_INSERT: // 强插
  323. pTask = new(std::nothrow) CTaskMonitorInsert(PduEntity);
  324. break;
  325. case PDU_CMD_AGENT_MONI_INTERCEPT: // 强截
  326. pTask = new(std::nothrow) CTaskMonitorGrab(PduEntity);
  327. break;
  328. case PDU_CMD_AGENT_MONI_CUT: // 强拆
  329. pTask = new(std::nothrow) CTaskMonitorCut(PduEntity);
  330. break;
  331. case PDU_CMD_AGENT_FAX: // 坐席传真
  332. pTask = new(std::nothrow) CTaskAgentFax(PduEntity);
  333. break;
  334. case PDU_CMD_AGENT_TURN_TO_IVR: // 坐席转IVR
  335. pTask = new(std::nothrow) CTaskAgentTurnIvr(PduEntity);
  336. break;
  337. case PDU_CMD_AGENT_MUTE: // 坐席静音
  338. pTask = new(std::nothrow) CTaskAgentMute(PduEntity);
  339. break;
  340. case PDU_CMD_IVR_HANGUP: // Ivr通知挂机
  341. pTask = new(std::nothrow) CTaskIvrHangUp(PduEntity);
  342. break;
  343. case PDU_CMD_IVR_TURN_AGENT: // IVR通知转坐席
  344. pTask = new(std::nothrow) CTaskIvrTurnAgent(PduEntity);
  345. break;
  346. case PDU_CMD_IVR_QUEUE_CONTINUE: // Ivr通知继续排队
  347. pTask = new(std::nothrow) CTaskIvrContinueQuene(PduEntity);
  348. break;
  349. case PDU_CMD_IVR_PLAY_DTMF: // IVR通知放音收按键
  350. pTask = new(std::nothrow) CTaskIvrPlayVoice(PduEntity);
  351. break;
  352. case PDU_CMD_IVR_CALL_OUT: // IVR呼叫
  353. pTask = new(std::nothrow) CTaskIvrCall(PduEntity);
  354. break;
  355. case PDU_CMD_IVR_TURN_OUTLINE: // IVR呼叫转移外线
  356. pTask = new(std::nothrow) CTaskIvrTurnOut(PduEntity);
  357. break;
  358. case PDU_CMD_IVR_FAX: // Ivr收发传真
  359. pTask = new(std::nothrow) CTaskIvrFax(PduEntity);
  360. break;
  361. case PDU_CMD_IVR_LEAVE_WORD: // Ivr留言
  362. pTask = new(std::nothrow) CTaskIvrLeaveWord(PduEntity);
  363. break;
  364. case PDU_CMD_AGENT_SEND_DTMF: // 坐席发送按键
  365. pTask = new(std::nothrow) CTaskAgentSendDtmf(PduEntity);
  366. break;
  367. default:
  368. break;
  369. }
  370. if(pTask == NULL) return;
  371. // 保存Task
  372. __addTask(pTask);
  373. // 返回Fase代表操作失败,移除该Task
  374. if(!pTask->DoTask())
  375. __onTaskFailed(pTask, PduEntity);
  376. else
  377. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, _T("{CTaskMgr}:DoTask[%s]TaskId[%ld]LineId[%d]时间[%ld]"), pTask->Name(), reinterpret_cast<LONG>(pTask), pTask->GetAssoLineId(), pTask->TaskTime());
  378. }
  379. /*****************************************************************
  380. **【函数名称】 onTaskPduMsg
  381. **【函数功能】 Task处理Pdu命令接口
  382. **【参数】 LineId: 线路ID
  383. PduEntity:消息实体
  384. **【返回值】
  385. ***************************************************************/
  386. void CTaskMgr::onTaskPduMsg( UINT LineId, CPduEntity &PduEntity )
  387. {
  388. CLogicLine* pLine = CLineHolder::GetInstance().getLogicLine(LineId);
  389. ASSERT(pLine != NULL);
  390. if(pLine == NULL)
  391. {
  392. ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{TaskMgr}: Task处理PDU命令失败, 无法定位关联线路[%d]"), LineId);
  393. return;
  394. }
  395. CTask* pTask = findTask(pLine->taskIdBinded());
  396. if(pTask == NULL)
  397. {
  398. pLine->taskIdBinded() = TASK_ID_INVALID;
  399. if(PduEntity.GetCmdType() == PDU_CMD_AGENT_CONFIRM_TRANSFER)
  400. {
  401. // 返回命令
  402. PduEntity.SetToExecReturn();
  403. PduEntity.SetDataBool(0, false);
  404. CNetInterface::getNetInstance()->Send(&PduEntity, PduEntity.GetLocalDevType(), PduEntity.GetLocalDevId());
  405. }
  406. }
  407. else
  408. {
  409. // task处理Pdu命令返回成功,删除task
  410. if(pTask->OnCmdOperation(PduEntity))
  411. removeTask((long)pTask);
  412. }
  413. }
  414. /*****************************************************************
  415. **【函数名称】 onMessage
  416. **【函数功能】 消息事件处理函数
  417. **【参数】 EvtType 消息事件类型
  418. lpContent 消息内容
  419. **【返回值】
  420. ****************************************************************/
  421. void CTaskMgr::onMessage( UINT MsgType, const PARAM lpContent )
  422. {
  423. if(lpContent == NULL) return;
  424. switch(MsgType)
  425. {
  426. case DEV_EVENT_LINE_OP_PROCESS: // 设备操作进展
  427. __procDevOpProcess(MsgType, lpContent);
  428. break;
  429. case DEV_EVENT_LINE_OP_RESULT: // 设备操作结果
  430. __procDevOpResult(MsgType, lpContent);
  431. break;
  432. case DEV_EVENT_DEV_OPERATOR: // 设备主动操作
  433. __procDevOperator(MsgType, lpContent);
  434. break;
  435. }
  436. }