EntitySessionManager.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513
  1. #if (defined _WIN32 || defined _WIN64)
  2. #include "stdafx.h"
  3. #endif
  4. #include "MessageType.h"
  5. #include "EntitySessionManager.h"
  6. #include "baseEx.h"
  7. #include<ctime>
  8. #include <string>
  9. #include "guitask/format.hpp"
  10. #include "../../Other/libpublicFun/publicFunExport.h"
  11. #include "boost/lexical_cast.hpp"
  12. namespace Chromium{
  13. static unsigned int m_global_transid = 0x0F000001; //用于替换来自web的transId,用来和框架进行交互
  14. static unsigned int m_createSession_transId = 0x00F00001; //用于建立本地session,为避免创建的sessionId重复
  15. auto createMapFun = []()->std::map<std::string, int> {
  16. std::map<std::string, int> nullMap;
  17. return nullMap;
  18. };
  19. std::map<std::string, int> EntitySessionManager::m_session_map = createMapFun();
  20. EntitySessionManager::EntitySessionManager(){
  21. m_global_transid = 0x0F000001;
  22. m_createSession_transId = 0x00F00001;
  23. }
  24. EntitySessionManager::~EntitySessionManager(){}
  25. std::pair<bool, int> EntitySessionManager::GetSessionIDByEntityName(std::string entityname){
  26. auto it = m_session_map.find(entityname);
  27. if (it == m_session_map.end())
  28. return std::make_pair(false, -1); // 发出 StartSession request
  29. return std::make_pair(true, it->second);
  30. }
  31. int EntitySessionManager::MakeNewTransID(CMessage* msg, unsigned int hdlID){
  32. WSClientReqInfo info;
  33. info.transID = msg->getTransID();
  34. info.hdlID = hdlID;
  35. info.next = NULL;
  36. m_trans_map.insert(std::pair<int, WSClientReqInfo>(m_global_transid, info));
  37. return m_global_transid++;
  38. }
  39. std::pair<bool, int> EntitySessionManager::getSrcTransID(int newTransID)
  40. {
  41. auto tmp = m_trans_map.find(newTransID);
  42. if (tmp != m_trans_map.end())
  43. return std::make_pair(true, tmp->second.transID);
  44. else
  45. {
  46. DbgEx("can not find transId:%d, may be true:%s", newTransID, newTransID & 0xF00000 ? "true" : "false");
  47. return std::make_pair(false, 0);
  48. }
  49. }
  50. void EntitySessionManager::StoreSessionReq(int transID, std::string entityName){
  51. m_session_ack_map.insert(std::pair<int, std::string>(transID, entityName));
  52. }
  53. std::vector<std::string> EntitySessionManager::queryUnLinkSession()
  54. {
  55. std::vector<std::string> ret;
  56. for (auto it : m_session_map)
  57. {
  58. if (it.second == -1)
  59. ret.push_back(it.first);
  60. }
  61. return ret;
  62. }
  63. std::map<std::string, int> EntitySessionManager::queryAllSessionInfo()
  64. {
  65. return m_session_map;
  66. }
  67. WSClientReqInfo* EntitySessionManager::ReduceOriginTransID(CMessage* msg){//获取transId对应的连接
  68. int tansId = msg->getTransID();
  69. std::map<int, WSClientReqInfo>::iterator it = m_trans_map.find(tansId);
  70. if (it == m_trans_map.end())
  71. return NULL;
  72. return &(it->second);
  73. }
  74. void EntitySessionManager::RemoveAckListNode(int transid){
  75. std::map<int, WSClientReqInfo>::iterator it = m_trans_map.find(transid);
  76. if (it == m_trans_map.end())
  77. return;
  78. m_trans_map.erase(it);
  79. return;
  80. }
  81. RequestProcessType EntitySessionManager::RequestProcess(CMessage* msg, std::string entityName, unsigned int hdlID){
  82. if (msg == NULL)
  83. return PROCESS_NOTHING;
  84. RequestProcessType ret = PROCESS_NOTHING;
  85. switch(msg->getMessageType()){
  86. case Info:
  87. ret = ProcessWithInfo(msg, entityName, hdlID);
  88. break;
  89. case BeginSession:
  90. ret = ProcessWithBeginSession(msg, entityName, hdlID);
  91. break;
  92. case EndSession:
  93. ret = ProcessWithEndSession(msg, entityName, hdlID);
  94. break;
  95. case Request:
  96. ret = ProcessWithRequest(msg, entityName, hdlID);
  97. break;
  98. case Register:
  99. ret = ProcessWithRegister(msg,entityName, hdlID);
  100. break;
  101. case Unregister:
  102. ret = ProcessWithUnregister(msg, entityName, hdlID);
  103. break;
  104. case Event:
  105. ret = PROCESS_SEND;
  106. break;
  107. case LogEventMsgType:
  108. ret = PROCESS_SEND;
  109. break;
  110. case LogWarnMsgType:
  111. return PROCESS_SEND;
  112. case SetVarReq:
  113. ret = ProcessWithSetVarReq(msg, entityName, hdlID);
  114. break;
  115. case GetVarReq:
  116. ret = ProcessWithGetVarReq(msg, entityName, hdlID);
  117. break;
  118. case Broadcast:
  119. return PROCESS_NOTHING;
  120. default:
  121. DbgEx("EntitySessionManager::RequestProcess switch default!");
  122. ret = PROCESS_NOTHING;
  123. }
  124. StoreSessionReq(msg->getTransID(), entityName);
  125. if (Request == msg->getMessageType())
  126. msg->exchangeSessionIdAndTransId();
  127. return ret;
  128. }
  129. RequestProcessType EntitySessionManager::ProcessWithInfo(CMessage* msg, std::string entityName, unsigned int hdlID){
  130. DbgEx("EntitySessionManager::ProcessWithInfo");
  131. auto s = GetSessionIDByEntityName(entityName);
  132. if (false == s.first || -1 == s.second)
  133. return PROCESS_NOTHING;
  134. msg->setSessionID(s.second, false);
  135. return PROCESS_SEND;
  136. }
  137. void EntitySessionManager::updateBeginSessionTime(std::string entityName, bool doCleanSessionTime)
  138. {
  139. time_t now_time = doCleanSessionTime ? 0 : time(NULL); //doCleanSessionTime 会重置记录时间为0,5s内重复发起的beginSession能被接受
  140. auto curSession = t_BeginSessionTime.find(entityName);
  141. if (curSession == t_BeginSessionTime.end())
  142. t_BeginSessionTime.insert(std::make_pair(entityName, now_time));
  143. else
  144. curSession->second = now_time;
  145. //DbgEx("save BeginSession Time:%s, %d", entityName.c_str(), now_time);
  146. }
  147. bool EntitySessionManager::checkBeginSession(std::string entityName)
  148. {
  149. time_t now_time = time(NULL);
  150. auto curSession = t_BeginSessionTime.find(entityName);
  151. if (curSession == t_BeginSessionTime.end() || curSession->second < now_time - 5)
  152. {
  153. DbgEx("checkBeginSession record begin session msg, oldTime:%lld, newTime:%lld", curSession != t_BeginSessionTime.end() ? curSession->second : -1, now_time);
  154. return true;//5s内不重复发起session
  155. }
  156. else
  157. return false;
  158. }
  159. RequestProcessType EntitySessionManager::ProcessWithBeginSession(CMessage* msg, std::string entityName, unsigned int hdlID){
  160. DbgEx("EntitySessionManager::ProcessWithBeginSession");
  161. auto s = GetSessionIDByEntityName(entityName);
  162. if (s.first && -1 != s.second)
  163. return PROCESS_FINDSESSION;
  164. if (checkBeginSession(entityName))
  165. {
  166. // 换transID 发送beginsession
  167. int transID = MakeNewTransID(msg, hdlID);
  168. msg->setTransID(transID);
  169. updateBeginSessionTime(entityName);
  170. return PROCESS_SEND;
  171. }
  172. else
  173. return PROCESS_RECORDMSG;//5s内发起过session
  174. }
  175. RequestProcessType EntitySessionManager::ProcessWithEndSession(CMessage* msg, std::string entityName,
  176. unsigned int hdlID){
  177. DbgEx("EntitySessionManager::ProcessWithEndSession");
  178. return PROCESS_NOTHING;
  179. }
  180. RequestProcessType EntitySessionManager::ProcessWithRequest(CMessage* msg, std::string entityName,
  181. unsigned int hdlID){
  182. DbgEx("EntitySessionManager::ProcessWithRequest");
  183. auto it = m_session_map.find(entityName);
  184. if (it == m_session_map.end() || -1 == it->second)
  185. {
  186. DbgEx("no session found for entity : %s", UtfToGbk(entityName.c_str()).c_str());
  187. return PROCESS_STARTSESSION;
  188. }
  189. msg->setSessionID(it->second, true);
  190. msg->setTransID(MakeNewTransID(msg,hdlID));
  191. return PROCESS_SEND;
  192. }
  193. RequestProcessType EntitySessionManager::ProcessWithRegister(CMessage* msg, std::string entityName, unsigned int hdlID){
  194. DbgEx("EntitySessionManager::ProcessWithRegister");
  195. auto it = m_session_map.find(entityName);
  196. if (it == m_session_map.end() || -1 == it->second)
  197. {
  198. DbgEx("no session found for entity : %s", UtfToGbk(entityName.c_str()).c_str());
  199. return PROCESS_STARTSESSION;
  200. }
  201. auto _broadcast_it = m_broadcast_map.find(entityName);
  202. if (_broadcast_it == m_broadcast_map.end())
  203. {
  204. // 尚未有客户端订阅过
  205. int transid = MakeNewTransID(msg, hdlID);
  206. msg->setTransID(transid);
  207. m_broadcast_map.insert(std::pair<std::string, int>(entityName, transid));
  208. return PROCESS_SEND;
  209. }
  210. std::map<int, WSClientReqInfo>::iterator _trans_it = m_trans_map.find(_broadcast_it->second);
  211. if (_trans_it == m_trans_map.end())
  212. {
  213. // 尚未有客户端订阅过
  214. int transid = MakeNewTransID(msg, hdlID);
  215. msg->setTransID(transid);
  216. m_broadcast_map.insert(std::pair<std::string, int>(entityName, transid));
  217. return PROCESS_SEND;
  218. }
  219. // 已经有过订阅 在链表后加
  220. WSClientReqInfo* pNode = &_trans_it->second;
  221. if (pNode->hdlID == hdlID)
  222. {
  223. // 该客户端订阅过,避免重复订阅
  224. return PROCESS_NOTHING;
  225. }
  226. while(pNode->next != NULL){
  227. if (pNode->hdlID == hdlID)
  228. {
  229. // 该客户端订阅过,避免重复订阅
  230. return PROCESS_NOTHING;
  231. }
  232. pNode = pNode->next;
  233. }
  234. // 该客户端从未订阅过
  235. pNode->next = new WSClientReqInfo();
  236. pNode->next->next = NULL;
  237. pNode->next->hdlID = hdlID;
  238. pNode->next->transID = msg->getTransID();
  239. return PROCESS_NOTHING;
  240. }
  241. RequestProcessType EntitySessionManager::ProcessWithUnregister(CMessage* msg, std::string entityName,
  242. unsigned int hdlID){
  243. DbgEx("EntitySessionManager::ProcessWithUnregister");
  244. std::map<std::string, int>::iterator _broadcast_it = m_broadcast_map.find(entityName);
  245. if (_broadcast_it == m_broadcast_map.end())
  246. {
  247. // 没订阅过 不用反注册
  248. return PROCESS_NOTHING;
  249. }
  250. // 订阅过 找到对应的客户端节点 删掉
  251. std::map<int, WSClientReqInfo>::iterator _trans_it = m_trans_map.find(_broadcast_it->second);
  252. if (_trans_it == m_trans_map.end())
  253. {
  254. // 没找到对应transid 理论上不可能
  255. m_broadcast_map.erase(_broadcast_it);
  256. return PROCESS_NOTHING;
  257. }
  258. // 查找节点删掉
  259. WSClientReqInfo* pNode = &_trans_it->second;
  260. if (pNode->hdlID == hdlID)
  261. {
  262. // 找到了就删掉
  263. if (pNode->next == NULL)
  264. {
  265. // 只有一个节点 就全都删掉
  266. m_trans_map.erase(_trans_it);
  267. m_broadcast_map.erase(_broadcast_it);
  268. return PROCESS_SEND;
  269. }
  270. // 后面有其他节点
  271. WSClientReqInfo* tp = pNode->next;
  272. pNode->transID = tp->transID;
  273. pNode->hdlID = tp->hdlID;
  274. pNode->next = tp->next;
  275. free(tp);
  276. return PROCESS_NOTHING;
  277. }
  278. // 首个节点不匹配时
  279. WSClientReqInfo* pHead = pNode;
  280. pNode = pNode->next;
  281. while(pNode != NULL){
  282. if (pNode->hdlID == hdlID)
  283. {
  284. pHead->next = pNode->next;
  285. free(pNode);
  286. return PROCESS_NOTHING;
  287. }
  288. pHead = pNode;
  289. pNode = pNode->next;
  290. }
  291. return PROCESS_NOTHING;
  292. }
  293. RequestProcessType EntitySessionManager::ProcessWithSetVarReq(CMessage* msg, std::string entityName,
  294. unsigned int hdlID){
  295. DbgEx("EntitySessionManager::ProcessWithSetVarReq");
  296. msg->setTransID(MakeNewTransID(msg, hdlID));
  297. return PROCESS_SEND;
  298. }
  299. RequestProcessType EntitySessionManager::ProcessWithGetVarReq(CMessage* msg, std::string entityName,
  300. unsigned int hdlID){
  301. DbgEx("EntitySessionManager::ProcessWithGetVarReq");
  302. msg->setTransID(MakeNewTransID(msg, hdlID));
  303. return PROCESS_SEND;
  304. }
  305. std::pair<int, std::string> EntitySessionManager::GetStartSessionRequest(std::string entityname, std::string className){
  306. auto curSession = m_createSession_transId++;
  307. std::string js = "{\"messageType\":1,\"transID\":" + std::to_string((LONGLONG)curSession) + ",\"functionName\":\"\",\"entity\":\"";
  308. js.append(entityname.append("\",\"class\":\""));
  309. js.append(className.append("\"}"));
  310. DbgEx("start sessionRequest: %s", UtfToGbk(js.c_str()).c_str());
  311. return std::make_pair(curSession, js);
  312. }
  313. std::pair<int, std::string> EntitySessionManager::GetAllSessionRequest(int transId)
  314. {
  315. std::map<std::string, std::string> sessionInfo;
  316. for (auto it : m_session_map)
  317. {
  318. if (it.second > 0)
  319. sessionInfo.insert(std::make_pair(it.first, boost::lexical_cast<std::string>(it.second)));
  320. }
  321. auto sessionJson = generateJsonStr(sessionInfo);
  322. if (sessionJson.first)
  323. {
  324. char sessionJs[10240] = "";
  325. sprintf(sessionJs, "{\"messageType\":%d,\"transID\":%d,\"%s\":%s}", 16, transId, PARAMLIST_HEAD, sessionJson.second.c_str());
  326. return std::make_pair(true, sessionJs);
  327. }
  328. return std::make_pair(false, "error generateJsonStr");
  329. }
  330. std::string EntitySessionManager::GetStartSessionAck(CMessage* msg, std::string entityname){
  331. auto s = GetSessionIDByEntityName(entityname);
  332. std::string sessionId = std::to_string((LONGLONG)s.second);
  333. std::string transid = std::to_string((LONGLONG)msg->getTransID());
  334. std::string js = "{\"messageType\":5,\"errorCode\":\"\",\"errorMsg\":\"\",\"sessionID\":";
  335. js.append(sessionId.c_str());
  336. js.append(",\"transID\":");
  337. js.append(transid.c_str());
  338. js.append("}");
  339. return js;
  340. }
  341. std::string EntitySessionManager::UpdateSessionMap(int transid, int sessionId)
  342. {
  343. auto it = m_session_ack_map.find(transid);
  344. if (it == m_session_ack_map.end())
  345. return "";
  346. DoSessionUpdate(it->second, sessionId);
  347. return it->second;
  348. }
  349. EntitySessionManager& EntitySessionManager::DoSessionUpdate(std::string entityname, int session)
  350. {
  351. auto sessionIt = m_session_map.find(entityname);
  352. bool needChange = true;
  353. if (m_session_map.end() != sessionIt)
  354. {
  355. if (sessionIt->second == session)
  356. needChange = false;
  357. m_session_map.erase(sessionIt);
  358. }
  359. if(needChange)
  360. DbgEx("update sessionId :<%s><%d>", entityname.c_str(), session);
  361. m_session_map.insert(std::make_pair(entityname, session));
  362. return *this;
  363. }
  364. AckProcessType EntitySessionManager::ProcessWithAck(CMessage* msg, unsigned int &hdlID){
  365. int globalID = msg->getTransID();
  366. WSClientReqInfoStruct* p = ReduceOriginTransID(msg);
  367. if (NULL == p)
  368. return ACKPROCESS_NOTHING;// 异常 应该不会有这种情况出现
  369. msg->setTransID(p->transID);
  370. hdlID = p->hdlID;
  371. UpdateSessionMap(globalID, msg->getSessionID());
  372. //RemoveAckListNode(globalID);
  373. if (hdlID == 0){
  374. return ACKPROCESS_NOTHING;
  375. }
  376. return ACKPROCESS_SEND;
  377. }
  378. std::pair<bool, std::string> EntitySessionManager::DoSessionRemove(unsigned int session)
  379. {
  380. for (auto it : m_session_map)
  381. {
  382. if (it.second == session)
  383. {
  384. DoSessionUpdate(it.first, -1);
  385. return std::make_pair(true, it.first);
  386. }
  387. }
  388. return std::make_pair(false, "");
  389. }
  390. std::pair<AckProcessType, std::string> EntitySessionManager::AskProcessSession(CMessage* msg, unsigned int &hdlID) {
  391. int globalID = msg->getTransID();
  392. /*
  393. 替换真实的transId
  394. */
  395. if (globalID & 0xF00000)
  396. hdlID = 0; ////本地transId,无记录的链接
  397. else
  398. {
  399. WSClientReqInfoStruct* p = ReduceOriginTransID(msg);
  400. if (NULL == p)
  401. return std::make_pair(ACKPROCESS_NOTHING, "can not find WSClient!");// 异常 应该不会有这种情况出现
  402. msg->setTransID(p->transID);
  403. hdlID = p->hdlID;
  404. }
  405. auto sessionId = msg->getSessionID();
  406. auto entityName = UpdateSessionMap(globalID, sessionId);
  407. if ("" == entityName)
  408. return std::make_pair(ACKPROCESS_NOTHING, "Update SessionMap error!");
  409. updateBeginSessionTime(entityName, -1 == sessionId); //clean the begin Sessiontime
  410. return std::make_pair(ACKPROCESS_SEND, entityName);
  411. }
  412. AckProcessType EntitySessionManager::ProcessWithRecvEvent(CMessage* msg, unsigned int &hdlID){
  413. WSClientReqInfoStruct* p = ReduceOriginTransID(msg);
  414. if (NULL == p)
  415. return ACKPROCESS_NOTHING;// 异常 应该不会有这种情况出现
  416. msg->setTransID(p->transID);
  417. hdlID = p->hdlID;
  418. if (hdlID == 0){
  419. return ACKPROCESS_NOTHING;
  420. }
  421. return ACKPROCESS_SEND;
  422. }
  423. AckProcessType EntitySessionManager::AskProcessEvent(CMessage *msg, std::vector<std::pair<int, int>> &transIdandHdlIDArr)
  424. {
  425. WSClientReqInfoStruct* p = ReduceOriginTransID(msg);
  426. if (NULL == p)
  427. return ACKPROCESS_NOTHING;
  428. transIdandHdlIDArr.clear();
  429. while (NULL != p)
  430. {
  431. if (0 != p->transID)
  432. transIdandHdlIDArr.push_back(std::make_pair(p->transID, p->hdlID));
  433. p = p->next;
  434. }
  435. if (transIdandHdlIDArr.size() > 0)
  436. return ACKPROCESS_SEND;
  437. else
  438. return ACKPROCESS_NOTHING;
  439. }
  440. AckProcessType EntitySessionManager::AckProcess(CMessage* msg, unsigned int &hdlID){
  441. AckProcessType ret = ACKPROCESS_NOTHING;
  442. switch(msg->getMessageType()){
  443. case Event:
  444. ProcessWithRecvEvent(msg, hdlID);
  445. break;
  446. case SessionAck:
  447. case RequestAck:
  448. case GetVarAck:
  449. case SetVarAck:
  450. ret = ProcessWithAck(msg, hdlID);
  451. break;
  452. default:
  453. DbgEx("AckProcess default!");
  454. ret = ACKPROCESS_NOTHING;
  455. }
  456. return ret;
  457. }
  458. }