mod_interactioncontext.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426
  1. #include "stdafx.h"
  2. #include "SpBase.h"
  3. #include "SpHelper.h"
  4. #include <map>
  5. // 交互上下文管理InteractionContext 0x309
  6. // 生命周期改成操作会话
  7. #include "InteractionContext_server_g.h"
  8. using namespace InteractionContext;
  9. #include "mod_assistantchannel/AssistantChannel_client_g.h"
  10. using namespace AssistantChannel;
  11. #include "mod_assistantchannel/chan_protocol.h"
  12. #define LOG_EVT_SELFCHECK_ASSISTANTCHANNEL_IDLE 0x50500001 //协助通道重启
  13. #define SYSVAR_CALLTYPE "CallType"
  14. #define CALLTYPE_NORMAL 'N' // 呼叫类型,普通模式
  15. #define CALLTYPE_MOBILE 'M' // 呼叫类型,手机模式
  16. class CInteractionContextEntity;
  17. class CtxSyncServerSession : public SyncService_ServerSessionBase
  18. {
  19. public:
  20. CtxSyncServerSession(CInteractionContextEntity* pEntity){m_pEntity = pEntity;}
  21. virtual void Handle_SetSessionData(SpOnewayCallContext<SyncService_SetSessionData_Info>::Pointer ctx);
  22. virtual void Handle_GetSessionData(SpReqAnsContext<SyncService_GetSessionData_Req, SyncService_GetSessionData_Ans>::Pointer ctx);
  23. virtual void Handle_SetMachineData(SpOnewayCallContext<SyncService_SetMachineData_Info>::Pointer ctx);
  24. virtual void Handle_GetMachineData(SpReqAnsContext<SyncService_GetMachineData_Req, SyncService_GetMachineData_Ans>::Pointer ctx);
  25. private:
  26. CInteractionContextEntity* m_pEntity;
  27. };
  28. class ChannelClient : public ChannelService_ClientBase
  29. {
  30. public:
  31. ChannelClient(CInteractionContextEntity* pEntity);
  32. virtual void OnMessage(ErrorCodeEnum Error, ChannelService_State_Info &Msg, CSmartPointer<IReleasable> pData);
  33. private:
  34. CInteractionContextEntity* m_pEntity;
  35. };
  36. using namespace InteractionContext;
  37. class CInteractionContextEntity : public CEntityBase,public ILogListener, public ISysVarListener
  38. {
  39. public:
  40. CInteractionContextEntity() : m_pChannelClient(NULL) {}
  41. virtual ~CInteractionContextEntity() {}
  42. virtual const char *GetEntityName() const { return "InteractionContext"; }
  43. virtual bool IsService()const{return true;}
  44. virtual void OnPreStart(CAutoArray<CSimpleStringA> strArgs,CSmartPointer<ITransactionContext> pTransactionContext)
  45. {
  46. LOG_FUNCTION();
  47. InitMachineData();
  48. ErrorCodeEnum Error = __OnStart(Error_Succeed);
  49. pTransactionContext->SendAnswer(Error);
  50. }
  51. ErrorCodeEnum __OnStart(ErrorCodeEnum preOperationError)
  52. {
  53. LOG_FUNCTION();
  54. CSmartPointer<IEntityFunction> pFunc = GetFunction();
  55. int i = 0;
  56. m_arrListener.Init(1);
  57. pFunc->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_SELFCHECK_ASSISTANTCHANNEL_IDLE,NULL,false);
  58. m_pChannelClient = new ChannelClient(this);
  59. ErrorCodeEnum Error = m_pChannelClient->Connect();
  60. if (Error == Error_Succeed) {
  61. ChannelService_BeginState_Sub Sub;
  62. Error = m_pChannelClient->BeginState(Sub);
  63. if (Error != Error_Succeed) {
  64. m_pChannelClient->GetFunction()->CloseSession();
  65. m_pChannelClient = NULL;
  66. }
  67. } else {
  68. m_pChannelClient->SafeDelete();
  69. m_pChannelClient = NULL;
  70. }
  71. {
  72. CSmartPointer<IEntityFunction> Func = GetFunction();
  73. CSimpleStringA strValue;
  74. Func->RegistSysVarEvent(SYSVAR_CALLTYPE, this);
  75. Func->GetSysVar(SYSVAR_CALLTYPE, strValue);
  76. if (strValue[0] == CALLTYPE_NORMAL)
  77. {
  78. m_nSysCallType = 0;
  79. }
  80. else if (strValue[0] == CALLTYPE_MOBILE)
  81. {
  82. m_nSysCallType = 1;
  83. }
  84. else
  85. {
  86. assert(0);
  87. }
  88. }
  89. return Error;
  90. }
  91. virtual void OnLog(const CAutoArray<CUUID> &SubIDs, const CUUID nLogID,const LogTypeEnum eLogType, const SeverityLevelEnum eLevel,
  92. const DWORD dwSysError,const DWORD dwUserCode,const DWORD dwEntityInstanceID, const WORD wEntityDevelID,
  93. const CAutoArray<DWORD> &Param, const char *pszEntityName, const char *pszModuleName,const char *pszMessage)
  94. {
  95. if (dwUserCode == LOG_EVT_SELFCHECK_ASSISTANTCHANNEL_IDLE)
  96. {
  97. Dbg("recv LOG_EVT_SELFCHECK_ASSISTANTCHANNEL_IDLE");
  98. if (m_pChannelClient!=NULL)
  99. {
  100. m_pChannelClient->GetFunction()->CloseSession();
  101. m_pChannelClient = NULL;
  102. Dbg("Close AssistChannel Session ");
  103. }
  104. if (m_pChannelClient == NULL)
  105. {
  106. Dbg("ReConnection AssistChannel Session");
  107. m_pChannelClient = new ChannelClient(this);
  108. ErrorCodeEnum Error = m_pChannelClient->Connect();
  109. if (Error != Error_Succeed)
  110. {
  111. m_pChannelClient->SafeDelete();
  112. m_pChannelClient = NULL;
  113. Dbg("AssistChannelClient connect fail!");
  114. }
  115. if (Error == Error_Succeed)
  116. {
  117. ChannelService_BeginState_Sub Sub;
  118. Error = m_pChannelClient->BeginState(Sub);
  119. if (Error != Error_Succeed)
  120. {
  121. LOG_TRACE("BeginState biz channel failed!");
  122. m_pChannelClient->GetFunction()->CloseSession();
  123. m_pChannelClient = NULL;
  124. }
  125. }
  126. }
  127. }
  128. }
  129. virtual void OnPreClose(EntityCloseCauseEnum eCloseCause,CSmartPointer<ITransactionContext> pTransactionContext)
  130. {
  131. ErrorCodeEnum Error = __OnClose(Error_Succeed);
  132. pTransactionContext->SendAnswer(Error);
  133. }
  134. ErrorCodeEnum __OnClose(ErrorCodeEnum preOperationError)
  135. {
  136. CSmartPointer<IEntityFunction> spFunction = GetFunction();
  137. for (int i = 0; i < m_arrListener.GetCount(); ++i)
  138. {
  139. spFunction->UnsubscribeLog(m_arrListener[i]);
  140. }
  141. spFunction->UnregistSysVarEvent(SYSVAR_CALLTYPE);
  142. m_pChannelClient->GetFunction()->CloseSession();
  143. m_pChannelClient = NULL;
  144. return Error_Succeed;
  145. }
  146. virtual CServerSessionBase *OnNewSession(const char* /*pszRemoteEntityName*/, const char * /*pszParam*/)
  147. {
  148. return new CtxSyncServerSession(this);
  149. }
  150. virtual void OnSysVarEvent(const char *pszKey, const char *pszValue,const char *pszOldValue,const char *pszEntityName)
  151. {
  152. if (_stricmp(pszKey, SYSVAR_CALLTYPE) == 0)
  153. {
  154. Dbg("sys calltype from: %c to %c", pszOldValue[0], pszValue[0]);
  155. if(pszValue[0] == CALLTYPE_NORMAL)
  156. {
  157. m_nSysCallType = 0;
  158. }
  159. else if(pszValue[0] == CALLTYPE_MOBILE)
  160. {
  161. m_nSysCallType = 1;
  162. }
  163. else
  164. {
  165. m_nSysCallType =-1;
  166. }
  167. }
  168. }
  169. CAutoBuffer SerializeTable()
  170. {
  171. SpBuffer buf;
  172. int size = (int)m_kvpTable.size();
  173. buf.OpenWrite();
  174. buf & size;
  175. for (KeyTable::iterator it = m_kvpTable.begin(); it != m_kvpTable.end(); ++it) {
  176. buf & it->second;
  177. }
  178. return buf.ToBuffer();
  179. }
  180. bool SetValue(int type, CSimpleStringA key, CSimpleStringA value);
  181. bool GetValue(int type, CSimpleStringA key, CSimpleStringA& value);
  182. void GetBlob(CSimpleStringA key, CSimpleStringA& value, CBlob &blob)
  183. {
  184. int nkey = key.GetLength();
  185. int nvalue = value.GetLength();
  186. SpBuffer buf;
  187. int cnt = 1;
  188. buf.OpenWrite(nkey + nvalue + 32);
  189. buf & cnt & key & value;
  190. blob = buf.ToBlob();
  191. }
  192. void SendSingleEntry(int type, CSimpleStringA key, CSimpleStringA& value)
  193. {
  194. if (m_pChannelClient)
  195. {
  196. if (m_nSysCallType == 0)
  197. {
  198. ChannelService_Send_Info Info;
  199. Info.compress = true;
  200. Info.encrypt = true;
  201. Info.sub_type = type;
  202. Info.type = ACM_TYPE_CTX;
  203. GetBlob(key, value, Info.data);
  204. m_pChannelClient->Send(Info);
  205. }
  206. else
  207. {
  208. Dbg("cur calltype cannot send pkt");
  209. }
  210. }
  211. }
  212. void GetTableBlob(int type, CBlob &blob)
  213. {
  214. SpBuffer buf;
  215. KeyTable& ktTable = type == ACM_CTX_MACHINE ? m_machineTable : m_kvpTable;
  216. int cnt = (int)ktTable.size();
  217. buf.OpenWrite();
  218. buf & cnt;
  219. for (KeyTable::iterator it = ktTable.begin(); it != ktTable.end(); ++it) {
  220. buf & it->first & it->second;
  221. }
  222. blob = buf.ToBlob();
  223. }
  224. void SendTableEntry(int type)
  225. {
  226. KeyTable& ktTable = type == ACM_CTX_MACHINE ? m_machineTable : m_kvpTable;
  227. if (m_pChannelClient && ktTable.size() > 0)
  228. {
  229. if (m_nSysCallType == 0)
  230. {
  231. ChannelService_Send_Info Info;
  232. Info.compress = true;
  233. Info.encrypt = true;
  234. Info.sub_type = type;
  235. Info.type = ACM_TYPE_CTX;
  236. GetTableBlob(type, Info.data);
  237. m_pChannelClient->Send(Info);
  238. }
  239. else
  240. {
  241. Dbg("cur calltype cannot send pkt");
  242. }
  243. }
  244. }
  245. void ClearSessionEntry()
  246. {
  247. m_kvpTable.clear();
  248. }
  249. private:
  250. void InitMachineData()
  251. {
  252. CSystemStaticInfo Info;
  253. GetFunction()->GetSystemStaticInfo(Info);
  254. m_machineTable["TerminalNo"] = Info.strTerminalID;
  255. m_machineTable["MachineType"] = Info.strMachineType;
  256. m_machineTable["MachineVersion"] = Info.MachineVersion.ToString();
  257. m_machineTable["Site"] = Info.strSite;
  258. m_machineTable["Screen"] = CSimpleStringA::Format("%d", Info.eScreen);
  259. m_machineTable["EnrolGPS"] = CSimpleStringA::Format("%f,%f", Info.EnrolGPS.GetLongitude(), Info.EnrolGPS.GetLatitude());
  260. m_machineTable["TerminalAddress"] = "";//Info.strEnrolAddr;
  261. m_machineTable["DelayTime"] = "0";
  262. }
  263. private:
  264. typedef std::map<CSimpleStringA, CSimpleStringA> KeyTable;
  265. KeyTable m_kvpTable;
  266. KeyTable m_machineTable;
  267. int m_local_version;
  268. int m_remote_version;
  269. ChannelClient *m_pChannelClient;
  270. CAutoArray<CUUID> m_arrListener;
  271. int m_nSysCallType;//0:普通模式,1:p2p模式
  272. };
  273. bool CInteractionContextEntity::SetValue(int type, CSimpleStringA key, CSimpleStringA value)
  274. {
  275. std::map<CSimpleStringA, CSimpleStringA>::iterator it;
  276. if (type == ACM_CTX_MACHINE)
  277. {
  278. it = m_machineTable.find(key);
  279. if (it == m_machineTable.end())
  280. {
  281. m_machineTable[key] = value;
  282. SendSingleEntry(type, key, value);
  283. return true;
  284. }
  285. }
  286. else if (type == ACM_CTX_SESSION)
  287. {
  288. it = m_kvpTable.find(key);
  289. if (it == m_kvpTable.end())
  290. {
  291. m_kvpTable[key] = value;
  292. SendSingleEntry(type, key, value);
  293. return true;
  294. }
  295. }
  296. it->second = value;
  297. SendSingleEntry(type, key, it->second);
  298. return true;
  299. }
  300. bool CInteractionContextEntity::GetValue(int type, CSimpleStringA key, CSimpleStringA& value)
  301. {
  302. std::map<CSimpleStringA, CSimpleStringA>::iterator it;
  303. if (type == ACM_CTX_MACHINE)
  304. {
  305. it = m_machineTable.find(key);
  306. if (it == m_machineTable.end())
  307. return false;
  308. }
  309. else if (type == ACM_CTX_SESSION)
  310. {
  311. it = m_kvpTable.find(key);
  312. if (it == m_kvpTable.end())
  313. return false;
  314. }
  315. value = it->second;
  316. return true;
  317. }
  318. void CtxSyncServerSession::Handle_SetSessionData(SpOnewayCallContext<SyncService_SetSessionData_Info>::Pointer ctx)
  319. {
  320. bool rt;
  321. rt = m_pEntity->SetValue(ACM_CTX_SESSION, ctx->Info.key, ctx->Info.data);
  322. }
  323. void CtxSyncServerSession::Handle_GetSessionData(SpReqAnsContext<SyncService_GetSessionData_Req, SyncService_GetSessionData_Ans>::Pointer ctx)
  324. {
  325. CSimpleStringA value;
  326. bool rt;
  327. Dbg("get session Data: key=%s", (LPCSTR)ctx->Req.key);
  328. rt = m_pEntity->GetValue(ACM_CTX_SESSION, ctx->Req.key,value);
  329. if (rt == true)
  330. {
  331. Dbg("founded, data=%s", (LPCSTR)value);
  332. ctx->Ans.value = value;
  333. ctx->Answer(Error_Succeed);
  334. }
  335. else
  336. {
  337. Dbg("not founded!");
  338. ctx->Answer(Error_NotExist);
  339. }
  340. }
  341. void CtxSyncServerSession::Handle_SetMachineData(SpOnewayCallContext<SyncService_SetMachineData_Info>::Pointer ctx)
  342. {
  343. bool rt;
  344. Dbg("Set machine Data: key=%s, data=%s", (LPCSTR)ctx->Info.key, (LPCSTR)ctx->Info.data);
  345. rt = m_pEntity->SetValue(ACM_CTX_MACHINE, ctx->Info.key, ctx->Info.data);
  346. }
  347. void CtxSyncServerSession::Handle_GetMachineData(SpReqAnsContext<SyncService_GetMachineData_Req, SyncService_GetMachineData_Ans>::Pointer ctx)
  348. {
  349. CSimpleStringA value;
  350. bool rt;
  351. Dbg("get machine Data: key=%s", (LPCSTR)ctx->Req.key);
  352. rt = m_pEntity->GetValue(ACM_CTX_MACHINE, ctx->Req.key,value);
  353. if (rt == true)
  354. {
  355. Dbg("founded, data=%s", (LPCSTR)value);
  356. ctx->Ans.value = value;
  357. ctx->Answer(Error_Succeed);
  358. }
  359. else
  360. {
  361. Dbg("not founded!");
  362. ctx->Answer(Error_NotExist);
  363. }
  364. }
  365. ChannelClient::ChannelClient( CInteractionContextEntity* pEntity ) : ChannelService_ClientBase(pEntity), m_pEntity(pEntity)
  366. {
  367. }
  368. void ChannelClient::OnMessage( ErrorCodeEnum Error, ChannelService_State_Info &Msg, CSmartPointer<IReleasable> pData)
  369. {
  370. if (Error == Error_Succeed) {
  371. switch(Msg.state)
  372. {
  373. case eChannelState_Connected:
  374. {
  375. m_pEntity->SendTableEntry(ACM_CTX_MACHINE);
  376. }
  377. break;
  378. case eChannelState_Idle:
  379. {
  380. m_pEntity->ClearSessionEntry();
  381. }
  382. break;
  383. default:
  384. break;
  385. }
  386. }
  387. }
  388. SP_BEGIN_ENTITY_MAP()
  389. SP_ENTITY(CInteractionContextEntity)
  390. SP_END_ENTITY_MAP()