中间件底层,websocket

SubjectRepository.cpp 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. #include "StdAfx.h"
  2. #include "SubjectRepository.h"
  3. #include "AgentOffice.h"
  4. #include "ExtenCtrl.h"
  5. #include "QueueMgr.h"
  6. #include "SubjectAgentState.h"
  7. #include "SubjectPhoneState.h"
  8. #include "SubjectIncomingCall.h"
  9. #include "SubjectAgentsOnSpecState.h"
  10. #include "SubjectTrunkUsageOfTask.h"
  11. CSubjectRepository::CSubjectRepository(CAgentOffice* pAgentOffice, CExtenCtrl* pExtenCtrl, CQueueMgr* pQueueMgr) :
  12. m_pAgentOffice(pAgentOffice), m_pExtenCtrl(pExtenCtrl), m_pQueueMgr(pQueueMgr)
  13. {
  14. __initSubjectMap();
  15. }
  16. CSubjectRepository::~CSubjectRepository(void)
  17. {
  18. __clearSubjectMap();
  19. }
  20. /*****************************************************************
  21. **【函数名称】 __initSubjectMap
  22. **【函数功能】 初始化主题索引表
  23. **【参数】
  24. **【返回值】
  25. ****************************************************************/
  26. void CSubjectRepository::__initSubjectMap( void )
  27. {
  28. CSubject* pSubject = NULL;
  29. // 座席状态主题
  30. pSubject = new CSubjectAgentState(this);
  31. m_SubjectMap.SetAt(SUBJECT_AGENT_STATUS, pSubject);
  32. // 分机状态主题
  33. pSubject = new CSubjectPhoneState(this);
  34. m_SubjectMap.SetAt(SUBJECT_PHONE_STATUS, pSubject);
  35. // 来电排队信息主题
  36. pSubject = new CSubjectIncomingCall(this);
  37. m_SubjectMap.SetAt(SUBJECT_CALL_QUEUED_NUM, pSubject);
  38. // 空闲座席列表主题
  39. pSubject = new CSubjectAgentsOnSpecState(this);
  40. m_SubjectMap.SetAt(SUBJECT_AGENT_FREE_LIST, pSubject);
  41. // 忙座席列表主题
  42. pSubject = new CSubjectAgentsOnSpecState(this);
  43. m_SubjectMap.SetAt(SUBJECT_AGENT_BUSY_LIST, pSubject);
  44. // 通话座席列表主题
  45. pSubject = new CSubjectAgentsOnSpecState(this);
  46. m_SubjectMap.SetAt(SUBJECT_AGENT_TALKING_LIST, pSubject);
  47. // 来电振铃座席列表主题
  48. pSubject = new CSubjectAgentsOnSpecState(this);
  49. m_SubjectMap.SetAt(SUBJECT_AGENT_ALTERING_LIST, pSubject);
  50. // 呼叫任务外线利用率主题
  51. pSubject = new CSubjectTrunkUsageOfTask(this);
  52. m_SubjectMap.SetAt(SUBJECT_TASK_TRUNK_USAGE, pSubject);
  53. // 呼叫任务外线利用率主题 ych 2018.5.5
  54. //pSubject = new CSubjectTrunkUsageOfTask(this);
  55. //m_SubjectMap.SetAt(SUBJECT_TASK_TRUNK_USAGE, pSubject);
  56. }
  57. /*****************************************************************
  58. **【函数名称】 __clearSubjectMap
  59. **【函数功能】 清空主题索引表
  60. **【参数】
  61. **【返回值】
  62. ****************************************************************/
  63. void CSubjectRepository::__clearSubjectMap( void )
  64. {
  65. POSITION pos = m_SubjectMap.GetStartPosition();
  66. while(pos != NULL)
  67. {
  68. UINT Key = 0;
  69. CSubject* pSubject = NULL;
  70. m_SubjectMap.GetNextAssoc(pos, Key, pSubject);
  71. delete pSubject;
  72. pSubject = NULL;
  73. } // end while
  74. m_SubjectMap.RemoveAll();
  75. }
  76. /*****************************************************************
  77. **【函数名称】 __getSubject
  78. **【函数功能】 得到指定类型的主题
  79. **【参数】 Type: 主题类型
  80. **【返回值】
  81. ****************************************************************/
  82. CSubject* CSubjectRepository::__getSubject( SUBJECT_TYPE Type )
  83. {
  84. CSubject* pSubject = NULL;
  85. m_SubjectMap.Lookup(Type, pSubject);
  86. ASSERT(pSubject != NULL);
  87. return pSubject;
  88. }
  89. /*****************************************************************
  90. **【函数名称】 registObserver
  91. **【函数功能】 注册订阅
  92. **【参数】 AgentId: 观查者座席工号
  93. Type: 订阅的主题类型
  94. Date: 订阅参数
  95. **【返回值】
  96. ****************************************************************/
  97. void CSubjectRepository::registObserver( UINT AgentId, SUBJECT_TYPE Type, int Data )
  98. {
  99. CSubject* pSubject = NULL;
  100. m_SubjectMap.Lookup(Type, pSubject);
  101. ASSERT(pSubject != NULL);
  102. if(pSubject != NULL)
  103. {
  104. m_RegistLock.Lock();
  105. pSubject->registObserver(AgentId, Data, Type);
  106. m_RegistLock.Unlock();
  107. }
  108. }
  109. /*****************************************************************
  110. **【函数名称】 removeObserver
  111. **【函数功能】 取消订阅
  112. **【参数】 AgentId: 观查者座席工号
  113. Type: 取消订阅的主题类型
  114. Data: 取消订阅参数
  115. **【返回值】
  116. ****************************************************************/
  117. void CSubjectRepository::removeObserver( UINT AgentId, SUBJECT_TYPE Type, int Data )
  118. {
  119. CSubject* pSubject = NULL;
  120. m_SubjectMap.Lookup(Type, pSubject);
  121. ASSERT(pSubject != NULL);
  122. if(pSubject != NULL)
  123. {
  124. m_RegistLock.Lock();
  125. pSubject->removeObserver(AgentId, Data);
  126. m_RegistLock.Unlock();
  127. }
  128. }
  129. /*****************************************************************
  130. **【函数名称】 clearObserver
  131. **【函数功能】 清除指定座席的所有订阅
  132. **【参数】 AgentId: 座席工号
  133. **【返回值】
  134. ****************************************************************/
  135. void CSubjectRepository::clearObserver( UINT AgentId )
  136. {
  137. m_RegistLock.Lock(); //2022-05-12
  138. POSITION pos = m_SubjectMap.GetStartPosition();
  139. while(pos != NULL)
  140. {
  141. UINT Key = 0;
  142. CSubject* pSubject = NULL;
  143. m_SubjectMap.GetNextAssoc(pos, Key, pSubject);
  144. pSubject->removeObserver(AgentId, -1);
  145. } // end while
  146. m_RegistLock.Unlock();
  147. }
  148. /*****************************************************************
  149. **【函数名称】 onAgentStateUpdated
  150. **【函数功能】 座席状态变化事件响应
  151. **【参数】 Id: 座席工号
  152. ExtId: 分机号
  153. State: 座席当前状态
  154. **【返回值】
  155. ****************************************************************/
  156. void CSubjectRepository::onAgentStateUpdated( UINT Id, UINT ExtId, int State, const CString& strGroup)
  157. {
  158. CSubject* pSubject = NULL;
  159. EventSubject info;
  160. CString szData;
  161. // 触发座席状态订阅事件
  162. m_RegistLock.Lock(); //2022-05-12
  163. pSubject = __getSubject(SUBJECT_AGENT_STATUS);
  164. if (pSubject != NULL)
  165. {
  166. // 2023-03-24 临时利用szData将组号保存到info中
  167. szData = strGroup;
  168. if (pSubject->incodeEvent(Id, ExtId, SUBJECT_AGENT_STATUS, State, &info, szData))
  169. pSubject->onEvent(&info, szData);
  170. } // end if
  171. // 触发空闲座席列表变化事件
  172. pSubject = __getSubject(SUBJECT_AGENT_FREE_LIST);
  173. if(pSubject != NULL)
  174. {
  175. if(pSubject->incodeEvent(0, 0, SUBJECT_AGENT_FREE_LIST, 0, &info, szData))
  176. pSubject->onEvent(&info, szData);
  177. } // end if
  178. // 触发忙座席列表变化事件
  179. pSubject = __getSubject(SUBJECT_AGENT_BUSY_LIST);
  180. if(pSubject != NULL)
  181. {
  182. if(pSubject->incodeEvent(0, 0, SUBJECT_AGENT_BUSY_LIST, 0, &info, szData))
  183. pSubject->onEvent(&info, szData);
  184. } // end if
  185. // 触发来电振铃座席列表变化事件
  186. pSubject = __getSubject(SUBJECT_AGENT_ALTERING_LIST);
  187. if(pSubject != NULL)
  188. {
  189. if(pSubject->incodeEvent(0, 0, SUBJECT_AGENT_ALTERING_LIST, 0, &info, szData))
  190. pSubject->onEvent(&info, szData);
  191. } // end if
  192. // 触发空闲通话列表变化事件
  193. pSubject = __getSubject(SUBJECT_AGENT_TALKING_LIST);
  194. if(pSubject != NULL)
  195. {
  196. if(pSubject->incodeEvent(0, 0, SUBJECT_AGENT_TALKING_LIST, 0, &info, szData))
  197. pSubject->onEvent(&info, szData);
  198. } // end if
  199. m_RegistLock.Unlock();
  200. }
  201. /*****************************************************************
  202. **【函数名称】 onPhoneStateUpdated
  203. **【函数功能】 分机状态变化事件响应
  204. **【参数】 Id: 分机关联座席工号
  205. ExtId: 分机号
  206. State: 分机当前状态
  207. **【返回值】
  208. ****************************************************************/
  209. void CSubjectRepository::onPhoneStateUpdated( UINT Id, UINT ExtId, int State )
  210. {
  211. // 只处理已关联座席的分机
  212. if(Id == 0)
  213. return;
  214. // 触发分机状态订阅事件
  215. EventSubject info;
  216. CString szData;
  217. m_RegistLock.Lock(); //2022-05-12
  218. CSubject* pSubject = __getSubject(SUBJECT_PHONE_STATUS);
  219. if(pSubject != NULL)
  220. {
  221. if(pSubject->incodeEvent(Id, ExtId, SUBJECT_PHONE_STATUS, State, &info,szData))
  222. pSubject->onEvent(&info, szData);
  223. } // end if
  224. m_RegistLock.Unlock();
  225. }
  226. /*****************************************************************
  227. **【函数名称】 onQueueStateUpdated
  228. **【函数功能】 排队状态变化事件响应
  229. **【参数】 Count: 等待排队的呼叫数量
  230. **【返回值】
  231. ****************************************************************/
  232. void CSubjectRepository::onQueueStateUpdated( UINT QueueNo, UINT Count )
  233. {
  234. // 触发来电呼叫数量变化订阅事件
  235. EventSubject info;
  236. CString szData;
  237. m_RegistLock.Lock(); //2022-05-12
  238. CSubject* pSubject = __getSubject(SUBJECT_CALL_QUEUED_NUM);
  239. if(pSubject != NULL)
  240. {
  241. if(pSubject->incodeEvent(QueueNo, 0, SUBJECT_CALL_QUEUED_NUM, Count, &info,szData))
  242. pSubject->onEvent(&info, szData);
  243. } // end if
  244. m_RegistLock.Unlock();
  245. }
  246. /*****************************************************************
  247. **【函数名称】 onTrunkUsageUpdated
  248. **【函数功能】 呼叫任务外线利用率变化事件响应
  249. **【参数】
  250. **【返回值】
  251. ****************************************************************/
  252. void CSubjectRepository::onTrunkUsageUpdated( UINT TaskId, UINT Usage )
  253. {
  254. // 呼叫任务外线利用率变化订阅事件
  255. EventSubject info;
  256. CString szData;
  257. m_RegistLock.Lock(); //2022-05-12
  258. CSubject* pSubject = __getSubject(SUBJECT_TASK_TRUNK_USAGE);
  259. if(pSubject != NULL)
  260. {
  261. if(pSubject->incodeEvent(TaskId, 0, SUBJECT_TASK_TRUNK_USAGE, Usage, &info, szData))
  262. pSubject->onEvent(&info, szData);
  263. } // end if
  264. m_RegistLock.Lock(); //2022-05-12
  265. }
  266. /*****************************************************************
  267. **【函数名称】 getAgentAssoExten
  268. **【函数功能】 得到指定座席的关联分机号
  269. **【参数】 AgentId: 座席工号
  270. **【返回值】
  271. ****************************************************************/
  272. UINT CSubjectRepository::getAgentAssoExten( UINT AgentId )
  273. {
  274. return m_pAgentOffice->getAgentAssoExten(AgentId);
  275. }
  276. /*****************************************************************
  277. **【函数名称】 getAgentAssoExtStatus
  278. **【函数功能】 得到指定座席的关联分机状态
  279. **【参数】 AgentId: 座席工号
  280. **【返回值】
  281. ****************************************************************/
  282. UINT CSubjectRepository::getAgentAssoExtState( UINT AgentId )
  283. {
  284. UINT ExtId = m_pAgentOffice->getAgentAssoExten(AgentId);
  285. return m_pExtenCtrl->getExtenState(ExtId);
  286. }
  287. /*****************************************************************
  288. **【函数名称】 getAgentStatus
  289. **【函数功能】 得到指定座席的当前状态
  290. **【参数】 AgentId: 座席工号
  291. **【返回值】
  292. ****************************************************************/
  293. UINT CSubjectRepository::getAgentState( UINT AgentId )
  294. {
  295. return m_pAgentOffice->getAgentState(AgentId);
  296. }
  297. CString CSubjectRepository::getAgentGroup(UINT AgentId)
  298. {
  299. return m_pAgentOffice->getAgentGroup(AgentId);
  300. }
  301. /*****************************************************************
  302. **【函数名称】 getIncomingCallCount
  303. **【函数功能】 读取等待排队的来电数量
  304. **【参数】
  305. **【返回值】
  306. ****************************************************************/
  307. UINT CSubjectRepository::getIncomingCallCount( UINT QueueNo )
  308. {
  309. return m_pQueueMgr->callCount(QueueNo);
  310. }
  311. /*****************************************************************
  312. **【函数名称】 getStateSpecAgentList
  313. **【函数功能】 获取指定订阅类型的座席列表
  314. **【参数】 Type: 订阅类型
  315. **【返回值】
  316. ****************************************************************/
  317. void CSubjectRepository::getStateSpecAgentList( SUBJECT_TYPE Type, CString& AgentList )
  318. {
  319. switch(Type)
  320. {
  321. case SUBJECT_AGENT_FREE_LIST: // 空闲座席列表
  322. m_pAgentOffice->getStateSpecAgentList(AGENT_LIST_FREE, AgentList);
  323. break;
  324. case SUBJECT_AGENT_BUSY_LIST: // 忙座席列表
  325. m_pAgentOffice->getStateSpecAgentList(AGENT_LIST_BUSY, AgentList);
  326. break;
  327. case SUBJECT_AGENT_ALTERING_LIST: // 来电振铃座席列表
  328. m_pAgentOffice->getStateSpecAgentList(AGENT_LIST_ALTERING, AgentList);
  329. break;
  330. case SUBJECT_AGENT_TALKING_LIST: // 通话座席列表
  331. m_pAgentOffice->getStateSpecAgentList(AGENT_LIST_TALKING, AgentList);
  332. break;
  333. } // end switch
  334. }