mod_chromium.cpp 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859
  1. #include "stdafx.h"
  2. #if (defined _WIN32 || defined _WIN64)
  3. #include <Windows.h>
  4. #include <WinUser.h>
  5. #include <tchar.h>
  6. #define SPLIT_SLASH_STR "\\"
  7. #else
  8. #include <signal.h>
  9. #include "toolkit.h"
  10. #include "path.h"
  11. #include "fileutil.h"
  12. #endif
  13. #include "baseEx.h"
  14. #include "CWebsocketServer.h"
  15. #include "mod_chromium.h"
  16. #include "base64.h"
  17. #include "CModTools.h"
  18. #include "cJSON.h"
  19. #include "SpIni.h"
  20. #include "CSocketClient.h"
  21. #include "processControl.h"
  22. #include <boost/chrono.hpp>
  23. #include <boost/bind.hpp>
  24. #include "../mod_upload/Upload_client_g.h"
  25. #include <tuple>
  26. #include <string>
  27. #include "EventCode.h"
  28. #ifdef OPEN_PERF
  29. #include <gperftools/profiler.h>
  30. #endif // OPEN_PERF
  31. #include <boost/date_time/posix_time/posix_time.hpp>
  32. #include "../mod_CameraConfigManage/Event.h"
  33. /*
  34. #define LOG_EVT_BEGIN_CAMERA_CONFIG 0x21D00001
  35. #define LOG_EVT_END_CAMERA_CONFIG 0x21D00002
  36. */
  37. /*no use
  38. #define MSG_EVT_STARTACTIVECAPTURE 0x31400001 //开始主动活体
  39. #define MSG_EVT_STOPACTIVECAPTURE 0x31400002 //停止主动活体
  40. #define LOG_EVT_SHOWACTIVECAPTUREMSG 0x31400003 //显示主动活体提示消息
  41. #define CLIENT_MANAGER_PATH "c:\\Program Files\\CmbWinPad\\CmbWinPad.exe"
  42. */
  43. #define COMPKEY_TERMINATE ((UINT_PTR) 0)
  44. #define COMPKEY_STATUS ((UINT_PTR) 1)
  45. #define COMPKEY_JOBOBJECT ((UINT_PTR) 2)
  46. namespace Chromium {
  47. void ChromiumSession::Handle_OpenBrowser(SpReqAnsContext<ChromiumSrv_OpenBrowser_Req, ChromiumSrv_OpenBrowser_Ans>::Pointer ctx)
  48. {
  49. LOG_FUNCTION();
  50. m_pEntity->OpenBrowser(ctx);
  51. }
  52. CChromiumEntity::CChromiumEntity() :m_pWsServer(NULL), m_iTcpBridgePort(4504), m_pTimerListener(NULL), m_strCustomMainUrl(true)
  53. , m_runAd(false), m_runMain(false), m_runExtend(false), m_runLogin(false), m_withBrowser(false), m_withMin(false), m_withClose(false)
  54. {
  55. DbgEx("CChromiumEntity constructor");
  56. //boost::thread(boost::bind(&CChromiumEntity::CefClintNotify, this)).detach(); //后台自动运行
  57. }
  58. CChromiumEntity::~CChromiumEntity()
  59. {
  60. if (NULL != m_pWsServer)
  61. {
  62. delete m_pWsServer;
  63. m_pWsServer = NULL;
  64. }
  65. //DeleteCriticalSection(&g_csInvokFreeRDP);
  66. }
  67. #if (defined _WIN32 || defined _WIN64)
  68. void CChromiumEntity::JobNotify() {
  69. TCHAR sz[2000] = _T("");
  70. BOOL fDone = FALSE;
  71. while (!fDone) {
  72. DWORD dwBytesXferred;
  73. ULONG_PTR CompKey;
  74. LPOVERLAPPED po;
  75. GetQueuedCompletionStatus(m_hIOCP, &dwBytesXferred, &CompKey, &po, INFINITE);
  76. fDone = (CompKey == COMPKEY_TERMINATE);
  77. if (CompKey == COMPKEY_JOBOBJECT) {
  78. switch (dwBytesXferred) {
  79. case JOB_OBJECT_MSG_END_OF_JOB_TIME:
  80. DbgEx("Job time limit reached");
  81. break;
  82. case JOB_OBJECT_MSG_END_OF_PROCESS_TIME:
  83. DbgEx("Job process (Id=%d) time limit reached", po);
  84. break;
  85. case JOB_OBJECT_MSG_ACTIVE_PROCESS_LIMIT:
  86. DbgEx("Too many active processes in job");
  87. break;
  88. case JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO:
  89. DbgEx("Job contains no active processes");
  90. break;
  91. case JOB_OBJECT_MSG_NEW_PROCESS:
  92. DbgEx("New process (Id=%d) in Job", po);
  93. break;
  94. case JOB_OBJECT_MSG_EXIT_PROCESS:
  95. DbgEx("Process (Id=%d) terminated", po);
  96. break;
  97. case JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS:
  98. DbgEx("Process (Id=%d) terminated abnormally", po);
  99. break;
  100. case JOB_OBJECT_MSG_PROCESS_MEMORY_LIMIT:
  101. DbgEx("Process (Id=%d) exceeded memory limit", po);
  102. break;
  103. case JOB_OBJECT_MSG_JOB_MEMORY_LIMIT:
  104. DbgEx("Process (Id=%d) exceeded job memory limit", po);
  105. break;
  106. default:
  107. DbgEx("Unknown notification: %d", dwBytesXferred);
  108. break;
  109. }
  110. CompKey = 1;
  111. }
  112. }
  113. }
  114. #endif
  115. void CChromiumEntity::OpenBrowser(SpReqAnsContext<ChromiumSrv_OpenBrowser_Req, ChromiumSrv_OpenBrowser_Ans>::Pointer ctx)
  116. {
  117. CSimpleStringA strUrl = ctx->Req.mainUrl;
  118. CSimpleStringA strUrl2 = ctx->Req.viceUrl;
  119. if (strUrl.IsNullOrEmpty()) {
  120. ctx->Answer(Error_Param);
  121. return;
  122. }
  123. auto ret = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::OutsideRequest, std::make_tuple(strUrl.GetData(), strUrl2.GetData()));
  124. ErrorCodeEnum result = ret.first;
  125. DbgEx("open request browser page %s return %d", (LPCTSTR)strUrl, result);
  126. ctx->Answer(result);
  127. }
  128. void CChromiumEntity::OnPaused() {
  129. #ifdef OPEN_PERF
  130. ProfilerStop();//停止性能分析
  131. #endif // OPEN_PERF
  132. }
  133. void CChromiumEntity::OnPreStart_Init(CAutoArray<CSimpleStringA>& strArgs, CSmartPointer<ITransactionContext>& pTransactionContext) {
  134. #ifdef OPEN_PERF
  135. auto profStr = CSimpleString::Format("chromiumAnalyze_%s.prof", generateTimeStr(true).c_str());
  136. std::thread([](std::string str) {
  137. ProfilerStart(str.c_str());//开启性能分析
  138. DbgEx("Generate chromiumAnalyze, %s", str.c_str());
  139. }, profStr.GetData()).detach();
  140. #endif // OPEN_PERF
  141. FetchCustomMainUrl(strArgs);
  142. CModTools::get_mutable_instance().InitCModTools(this);
  143. CModTools::get_mutable_instance().killAllChromium();
  144. DoBrowserCacheClearJob();
  145. #if (defined _WIN32 || defined _WIN64)
  146. #else
  147. CSimpleStringA strDbgPath;
  148. GetFunction()->GetPath("Dbg", strDbgPath);
  149. set_traceback_path(strDbgPath.GetData());
  150. boost::thread([]() {
  151. for (auto i = 1; i < 28; i++)
  152. {
  153. if (SIGTERM == i)
  154. signal(i, [](int signum)->void {
  155. DbgEx("receive signal:%d, closeChromium", signum);
  156. CModTools::get_mutable_instance().killAllChromiumByThread(3);
  157. CWebsocketServer::stopServer();
  158. signal(signum, SIG_DFL);
  159. raise(signum);
  160. });
  161. else if (SIGSEGV == i || SIGABRT == i)
  162. signal(i, &seg_signal_handler);
  163. else if (SIGPROF == i || SIGALRM == i || SIGVTALRM == i)
  164. continue;
  165. else
  166. signal(i, &normal_signal_handle);
  167. }
  168. }).detach();
  169. #endif
  170. GetFunction()->GetSystemStaticInfo(m_sysInfo);
  171. if (!IsConfigMode()) {
  172. CSmartPointer<IConfigInfo> spConfig;
  173. if (Error_Succeed == GetFunction()->OpenConfig(Config_CenterSetting, spConfig))//特别坑,这个OpenConfig返回一直都是success
  174. {
  175. auto webMaskKey = CSimpleString::Format("WebMask_%s", m_sysInfo.strMachineType.GetData());
  176. CSimpleString webMaskStr;
  177. if (Error_Succeed == spConfig->ReadConfigValue("Chromium", webMaskKey.GetData(), webMaskStr))
  178. {
  179. auto maskArr = webMaskStr.Split('|');
  180. for (int i = 0; i < maskArr.GetCount(); i++)
  181. {
  182. auto trimStr = maskArr[i].Trim();
  183. if (!trimStr.Compare("ad", true))
  184. m_runAd = true;
  185. else if (!trimStr.Compare("main", true))
  186. m_runMain = true;
  187. else if (!trimStr.Compare("extend", true))
  188. m_runExtend = true;
  189. else if (!trimStr.Compare("login", true))
  190. m_runLogin = true;
  191. else if (!trimStr.Compare("with_browser", true))
  192. m_withBrowser = true;
  193. else if (!trimStr.Compare("with_min", true))
  194. m_withMin = true;
  195. else if (!trimStr.Compare("with_close", true))
  196. m_withClose = true;
  197. }
  198. #if (defined _WIN32 || defined _WIN64)
  199. #else
  200. m_runAd = m_runMain = true;
  201. m_runExtend = m_runLogin = m_withBrowser = m_withMin = m_withClose = false;
  202. #endif
  203. DbgEx("MachineType: %s, find %s, readStr:%s, m_runAd:%d, m_runMain:%d, m_runExtend:%d, m_runLogin:%d, m_withBrowser:%d, with_min:%d, with_close:%d",
  204. m_sysInfo.strMachineType.GetData(), webMaskKey.GetData(), webMaskStr.GetData(), m_runAd, m_runMain, m_runExtend, m_runLogin, m_withBrowser
  205. ,m_withMin, m_withClose);
  206. if (m_withMin)
  207. CModTools::get_mutable_instance().setWithMin(m_withMin);
  208. if (m_withClose)
  209. CModTools::get_mutable_instance().setWithClose(m_withClose);
  210. }
  211. else
  212. DbgEx("can not find %s, use default", webMaskKey.GetData());
  213. }
  214. if (!m_runAd && !m_runMain && !m_runExtend && !m_withBrowser && !CModTools::get_mutable_instance().IsConfigWork())
  215. {
  216. DbgEx("can not open centerSetting, maybe fault");
  217. if (!(m_sysInfo.strMachineType.IsEndWith("PAD", true) || m_sysInfo.strMachineType.IsEndWith("Stand2S", true)))
  218. {
  219. m_withBrowser = true;
  220. DbgEx("since is %s, so m_withBrowser:%d", m_sysInfo.strMachineType.GetData(), m_withBrowser);
  221. }
  222. }
  223. #if (defined _WIN32 || defined _WIN64)
  224. if (!logProducer)
  225. logProducer = create_log_producer_storage("cefclient", "0", "");
  226. #endif
  227. std::string magicStr = CModTools::get_mutable_instance().getMagicStr();
  228. boost::thread(boost::bind(SaveCefclientLog, magicStr)).detach();
  229. }
  230. }
  231. bool CChromiumEntity::OnPreStart_socketStart(CAutoArray<CSimpleStringA>& strArgs, CSmartPointer<ITransactionContext>& pTransactionContext)
  232. {
  233. ErrorCodeEnum Error;
  234. if (Error_Succeed != (Error = GetFunction()->StartTcpBridgeServer(m_iTcpBridgePort)))
  235. {
  236. DbgEx("start tcp bridge server failed!");
  237. pTransactionContext->SendAnswer(Error);
  238. return false;
  239. }
  240. // load all struct define xml & start websocket server
  241. CSimpleStringA strStructPath;
  242. GetFunction()->GetPath("Base", strStructPath);
  243. strStructPath.Append(CSimpleStringA(SPLIT_SLASH_STR) + "res" + SPLIT_SLASH_STR + "StructConfig" + SPLIT_SLASH_STR);
  244. DbgEx("find struct config files in path %s", strStructPath.GetData());
  245. m_pWsServer = new CWebsocketServer(strStructPath, this);
  246. m_pWsServer->run();
  247. return true;
  248. }
  249. bool CChromiumEntity::OnPreStart_register(CAutoArray<CSimpleStringA>& strArgs, CSmartPointer<ITransactionContext>& pTransactionContext)
  250. {
  251. ErrorCodeEnum Error;
  252. //与browser进行交互所必须,移除browser的机型不需要订阅browser相关
  253. if (m_withBrowser)
  254. {
  255. if (Error_Succeed != (Error = GetFunction()->SubscribeBroadcast("IEBrowser", "CustomerCmd", this, m_uidBrowserListenser))) {
  256. DbgEx("subscribe browser CustomerCmd failed!");
  257. pTransactionContext->SendAnswer(Error);
  258. }
  259. else
  260. DbgEx("subscribe browser CustomerCmd success!");
  261. if (Error_Succeed != (Error = GetFunction()->SubscribeLog(m_uidCameraListener, this, Log_Event, Severity_None, Error_IgnoreAll, -1, "CameraConfigManage")))
  262. DbgEx("subscribe Camera log failed!"); //非必须
  263. }
  264. if (!m_withBrowser)
  265. {//有browser的时候不需要订阅这一堆
  266. Error = GetFunction()->SubscribeLog(m_uuidAccessAuth, this, Log_Event, Severity_None, Error_IgnoreAll, -1, "AccessAuthorization");
  267. if (Error != Error_Succeed)
  268. DbgEx("subscribe AccessAuthorization log failed!");
  269. else
  270. DbgEx("subscribe AccessAuthorization success!");
  271. if (Error_Succeed != GetFunction()->RegistSysVarEvent("UIState", this))
  272. DbgEx("RegistSysVarEvent UIState failed!");
  273. if (Error_Succeed != GetFunction()->RegistSysVarEvent("TerminalStage", this))
  274. DbgEx("RegistSysVarEvent TerminalStage failed!");
  275. if (Error_Succeed != GetFunction()->RegistSysVarEvent("EntryPermit", this))
  276. DbgEx("RegistSysVarEvent EntryPermit failed!");
  277. if (Error_Succeed != GetFunction()->RegistSysVarEvent("SessionID", this))
  278. DbgEx("RegistSysVarEvent SessionID failed!");
  279. if (Error_Succeed != GetFunction()->RegistSysVarEvent("CustomerID", this))
  280. DbgEx("RegistSysVarEvent CustomerID failed!");
  281. if (Error_Succeed != GetFunction()->RegistSysVarEvent("CardStoreInUse", this))
  282. DbgEx("RegistSysVarEvent CardStoreInUse failed!");
  283. }
  284. #if (defined _WIN32 || defined _WIN64)
  285. //未定义Log_Notify
  286. #else
  287. Error = GetFunction()->SubscribeLog(m_uuidAllFault, this, Log_Notify, Severity_High, Error_IgnoreAll, -2, NULL, false);
  288. if (Error_Succeed == Error) {
  289. this->GetFunction()->GetPrivilegeFunction()->RefreshFrameworkState(FrameworkState_NotDisturb);
  290. }
  291. else {
  292. DbgEx("subscribe log for notify failed! %s", SpStrError(Error));
  293. }
  294. #endif
  295. return true;
  296. }
  297. bool CChromiumEntity::OnPreStart_openWeb(CAutoArray<CSimpleStringA>& strArgs, CSmartPointer<ITransactionContext>& pTransactionContext)
  298. {
  299. //generateBussinessLimitTimer();
  300. if (m_runAd) openAdPage();
  301. if (m_runExtend) openExtendPage();
  302. if (m_runMain)
  303. {
  304. //openMainPage(); return true;
  305. CSimpleStringA t_EntryPermit, t_terminalState;
  306. GetFunction()->GetSysVar("EntryPermit", t_EntryPermit);
  307. GetFunction()->GetSysVar("TerminalStage", t_terminalState);
  308. /** Z开头标识终端配种模式 [Gifur@20211017]*/
  309. if ('A' != t_terminalState[0] && 'Z' != t_terminalState[0])
  310. {
  311. if ('X' == t_terminalState[0])
  312. {
  313. DbgEx("do not begin accessAuth, terminalStage X, do nothing.");
  314. }
  315. else if (!m_withBrowser)
  316. {
  317. auto openRet = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::breakdown,
  318. std::tuple <std::string, std::string>(m_sysInfo.strTerminalID.GetData(), generateTimeStr()));
  319. DbgEx("access failed, open page breakdown %s, %d", Error_Succeed == openRet.first ? "success" : "fail", openRet.second);
  320. }
  321. }
  322. else
  323. openMainPage();
  324. }
  325. return true;
  326. }
  327. void CChromiumEntity::openMainPage()
  328. {
  329. #if (defined _WIN32 || defined _WIN64)
  330. generateCefclientTimer();
  331. #else
  332. CSystemRunInfo sysruninfo;
  333. GetFunction()->GetSystemRunInfo(sysruninfo);
  334. if (!(sysruninfo.dwBootOption & SystemBootOptionEnum::BootOption_Test))
  335. generateCefclientTimer();//非--test时,才会打开浏览器
  336. #endif
  337. }
  338. void CChromiumEntity::openAdPage()
  339. {
  340. auto openRet = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::Ad);
  341. DbgEx("open page Ad %s, pid:%d", Error_Succeed == openRet.first ? "success" : "fail", openRet.second);
  342. }
  343. void CChromiumEntity::openExtendPage()
  344. {
  345. auto openRet = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::extend);
  346. DbgEx("open page extend %s, pid:%d", Error_Succeed == openRet.first ? "success" : "fail", openRet.second);
  347. }
  348. void CChromiumEntity::OnPreStart(CAutoArray<CSimpleStringA> strArgs, CSmartPointer<ITransactionContext> pTransactionContext)
  349. {
  350. OnPreStart_Init(strArgs, pTransactionContext);//初始化部分, perf ,killchromium, signal, get custom url
  351. if (!OnPreStart_socketStart(strArgs, pTransactionContext)) {
  352. return;
  353. }
  354. if (!IsConfigMode()) {
  355. if (!OnPreStart_register(strArgs, pTransactionContext)) {
  356. return;
  357. }
  358. if (!OnPreStart_openWeb(strArgs, pTransactionContext)) {
  359. return;
  360. }
  361. }
  362. pTransactionContext->SendAnswer(Error_Succeed);
  363. }
  364. bool CChromiumEntity::CheckIsCardStore() {
  365. return m_sysInfo.strMachineType.IsEndWith("CardStore", true) || m_sysInfo.strMachineType.IsEndWith("CardPrinter", true);
  366. }
  367. void CChromiumEntity::OnSysVarEvent(const char* pszKey, const char* pszValue, const char* pszOldValue, const char* pszEntityName)
  368. {
  369. DbgEx("OnSysVarEvent %s, old->new:%s->%s", pszKey, pszOldValue, pszValue);
  370. if ((strnicmp(pszKey, "UIState", strlen("UIState")) == 0))
  371. {
  372. if (strnicmp(pszValue, "M", strlen("M")) == 0)
  373. {
  374. static bool firstEnter = true;
  375. if (firstEnter)
  376. {
  377. firstEnter = false;
  378. DbgEx("first Enter main page");
  379. m_firstStartMain.unlock();
  380. }
  381. GetFunction()->UnregistSysVarEvent("UIState");
  382. }
  383. }
  384. else if (0 == CSimpleStringA("TerminalStage").Compare(pszKey, true))
  385. {
  386. if (0 == CSimpleStringA("A").Compare(pszValue, true))
  387. {
  388. if(CModTools::get_mutable_instance().IsConfigWork())//url正常时才关闭
  389. {
  390. CModTools::get_mutable_instance().StopChromiumBrowser(ERR_PAGE_REASON::breakdown);
  391. openMainPage();
  392. //DbgEx("UnregistSysVarEvent TerminalStage %s", Error_Succeed == GetFunction()->UnregistSysVarEvent("TerminalStage") ? "success" : "fail");
  393. }
  394. }
  395. else if (0 == CSimpleStringA("X").Compare(pszValue, true))
  396. DbgEx("TerminalStage X, do nothing.");
  397. else
  398. {
  399. if (!m_withBrowser)
  400. {
  401. auto openRet = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::breakdown,
  402. std::tuple < std::string, std::string>(m_sysInfo.strTerminalID.GetData(), generateTimeStr()));
  403. DbgEx("access failed, open page breakdown %s, %d", Error_Succeed == openRet.first ? "success" : "fail", openRet.second);
  404. }
  405. }
  406. }
  407. else if (0 == CSimpleStringA("CardStoreInUse").Compare(pszKey, true) && CheckIsCardStore())
  408. {
  409. auto openRet = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::CardStoreIsBusy,
  410. std::tuple <std::string, std::string>(m_sysInfo.strTerminalID.GetData(), generateTimeStr()));
  411. DbgEx("CardStoreIsBusy, open page CardStoreIsBusy %s, %d", Error_Succeed == openRet.first ? "success" : "fail", openRet.second);
  412. }
  413. }
  414. void CChromiumEntity::OnPreClose(EntityCloseCauseEnum eCloseCause, CSmartPointer<ITransactionContext> pTransactionContext)
  415. {
  416. exitClean();
  417. pTransactionContext->SendAnswer(Error_Succeed);
  418. }
  419. void CChromiumEntity::exitClean()
  420. {
  421. static bool isExit = false;
  422. if (!isExit)
  423. {
  424. isExit = true;
  425. CModTools::get_mutable_instance().killAllChromiumByThread(3);
  426. delete m_pWsServer;
  427. if (m_pTimerListener != NULL)
  428. {
  429. GetFunction()->KillTimer(CHROMIUM_TIMER_ID);
  430. delete m_pTimerListener;
  431. m_pTimerListener = NULL;
  432. }
  433. GetFunction()->UnsubscribeBroadcast("IEBrowser");
  434. }
  435. }
  436. /** 查看启动顺序发现集中配置实体启动在本实体之前,无法调用集中配置的接口,随将实现搬到这里来 [Gifur@2021124]*/
  437. void CChromiumEntity::FetchCustomMainUrl(CAutoArray<CSimpleStringA>& strArgs)
  438. {
  439. const int ArgsCount = strArgs.GetCount();
  440. LOG_TRACE("strArgs.GetCount() = %d", ArgsCount);
  441. for (int i = 0; i < ArgsCount; ++i) {
  442. DbgEx("strArgs[%d] = %s", i, strArgs[i].GetData());
  443. }
  444. if (ArgsCount == 1) {
  445. m_strCustomMainUrl = strArgs[0];
  446. DbgEx("Get custom main url: %s", m_strCustomMainUrl.GetData());
  447. if (!m_strCustomMainUrl.IsNullOrEmpty()) {
  448. LogWarn(Severity_High, Error_Debug, LOG_EVT_CHROMIUM_DETECT_CUSTOM_FULTURE_URL_FROM_START,
  449. CSimpleStringA::Format("从模块入参获取自定义链接:%s", m_strCustomMainUrl.GetData()));
  450. }
  451. } else {
  452. CSmartPointer<IConfigInfo> pConfig;
  453. GetFunction()->OpenConfig(Config_Cache, pConfig);
  454. int cnt(0), currentUsing(0);
  455. pConfig->ReadConfigValueInt("CustomWebUrl", "Count", cnt);
  456. pConfig->ReadConfigValueInt("CustomWebUrl", "Current", currentUsing);
  457. if (cnt > 0 && currentUsing > 0) {
  458. CSimpleStringA strAdUrl(true);
  459. CSimpleStringA strSection = CSimpleStringA::Format("CustomWebUrl%d", currentUsing);
  460. pConfig->ReadConfigValue(strSection, "FultureUrl", m_strCustomMainUrl);
  461. pConfig->ReadConfigValue(strSection, "AdUrl", strAdUrl);
  462. if (!m_strCustomMainUrl.IsNullOrEmpty()) {
  463. LogWarn(Severity_High, Error_Debug, LOG_EVT_CHROMIUM_DETECT_CUSTOM_FULTURE_URL_FROM_CONFIG,
  464. CSimpleStringA::Format("从本地维护桌面获取自定义链接:%s", m_strCustomMainUrl.GetData()));
  465. }
  466. }
  467. }
  468. }
  469. #if (defined _WIN32 || defined _WIN64)
  470. void CChromiumEntity::OnLog(const CAutoArray<CUUID>& SubIDs, const CUUID nLogID, const LogTypeEnum eLogType, const SeverityLevelEnum eLevel,
  471. const DWORD dwSysError, const DWORD dwUserCode, const DWORD dwEntityInstanceID, const WORD wEntityDevelID,
  472. const CAutoArray<DWORD>& Param, const char* pszEntityName, const char* pszModuleName, const char* pszMessage, const linkContext& pLinkInfo)
  473. #else
  474. void CChromiumEntity::OnLog(const CAutoArray<CUUID>& SubIDs, const CUUID nLogID, const LogTypeEnum eLogType, const SeverityLevelEnum eLevel,
  475. const DWORD dwSysError, const DWORD dwUserCode, const DWORD dwEntityInstanceID, const WORD wEntityDevelID,
  476. const CAutoArray<DWORD>& Param, const char* pszEntityName, const char* pszModuleName, const char* pszMessage)
  477. #endif
  478. {
  479. DbgEx("OnLog %x from entity %s, msg : %s", dwUserCode, NULL == pszEntityName ? "" : pszEntityName, NULL == pszMessage ? "" : pszMessage);
  480. #if (defined _WIN32 || defined _WIN64)
  481. //No Log_Notify
  482. #else
  483. if (Log_Notify == eLogType)
  484. {
  485. try {
  486. cJSON* pJson = cJSON_Parse(pszMessage);
  487. auto notifyReason = cJSON_GetObjectItem(pJson, "reason")->valuestring;
  488. auto notifymsg = cJSON_GetObjectItem(pJson, "errmsg")->valuestring;
  489. auto notiryRebootTime = cJSON_GetObjectItem(pJson, "rebootTime")->valuestring;
  490. auto notifyPool = m_pWsServer->getNotifyPool();
  491. if (notifyPool.size() > 0)
  492. {
  493. for (auto it : notifyPool)
  494. {
  495. DbgEx("Log_Notify err, notifyPool to %d, %d", it.first, it.second);
  496. m_pWsServer->do_send_notifyMsg(it.first, it.second, notifyReason, notifymsg, notiryRebootTime, dwSysError, dwUserCode);
  497. }
  498. }
  499. else
  500. {
  501. auto openRet = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::ErrNotify, { m_sysInfo.strTerminalID.GetData(), generateTimeStr() }, { notifyReason, notifymsg, notiryRebootTime, dwSysError, dwUserCode });
  502. DbgEx("Log_Notify err, open page %s, %d", Error_Succeed == openRet.first ? "success" : "fail", openRet.second);
  503. }
  504. }
  505. catch (std::exception& e) {
  506. DbgEx("Log_Notify err, %s", e.what());
  507. }
  508. return;
  509. }
  510. #endif
  511. switch (dwUserCode)
  512. {
  513. case LOG_EVT_BEGIN_CAMERA_CONFIG://no use
  514. {
  515. auto openRet = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::CameraConfig,
  516. std::tuple < std::string, std::string>(m_sysInfo.strTerminalID.GetData(), generateTimeStr()));
  517. DbgEx("show Screen Camera config, open page cameraconfig %s, %d", Error_Succeed == openRet.first ? "success" : "fail", openRet.second);
  518. }
  519. break;
  520. case LOG_EVT_END_CAMERA_CONFIG://no use
  521. DbgEx("end show Screen Camera config, close page cameraconfig");
  522. CModTools::get_mutable_instance().killChromiumByName((+PAGE_TYPE::CameraConfig)._to_string());
  523. break;
  524. default:
  525. break;
  526. }
  527. }
  528. void CChromiumEntity::OnTerminalManage(const char* pszEntityName, DWORD dwMessageId, DWORD dwMessageSignature, HealthManager::TerminalManager& evt)
  529. {
  530. DbgEx("OnTerminalManage : evt.op = %d", evt.op);
  531. switch (evt.op)
  532. {
  533. case 0:
  534. GetFunction()->SetSysVar("TerminalManagerState", "L", true);
  535. {
  536. auto openRet = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::TerminalManagerOff,
  537. std::tuple < std::string, std::string>(m_sysInfo.strTerminalID.GetData(), generateTimeStr()));
  538. DbgEx("TerminalManagerState L, open page TerminalManagerOff %s, %d", Error_Succeed == openRet.first ? "success" : "fail", openRet.second);
  539. }
  540. break;
  541. case 1:
  542. GetFunction()->SetSysVar("TerminalManagerState", "N", true);
  543. {
  544. DbgEx("TerminalManagerState N, try close TerminalManager");
  545. CModTools::get_mutable_instance().killChromiumByName((+PAGE_TYPE::TerminalManager)._to_string());
  546. }
  547. break;
  548. case 2:
  549. GetFunction()->SetSysVar("TerminalManagerState", "K", true);
  550. {
  551. auto openRet = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::TerminalManagerKickOut,
  552. std::tuple < std::string, std::string>(m_sysInfo.strTerminalID.GetData(), generateTimeStr()));
  553. DbgEx("TerminalManagerState K, open page TerminalManagerKickOut %s, %d", Error_Succeed == openRet.first ? "success" : "fail", openRet.second);
  554. }
  555. break;
  556. case 99:
  557. GetFunction()->SetSysVar("TerminalManagerState", "N", true);
  558. {
  559. DbgEx("TerminalManagerState N, try close TerminalManager");
  560. CModTools::get_mutable_instance().killChromiumByName((+PAGE_TYPE::TerminalManager)._to_string());
  561. }
  562. break;
  563. default:
  564. break;
  565. }
  566. }
  567. void CChromiumEntity::OnBusinessLimitTimerListener(void* pData)
  568. {
  569. DbgEx("定时任务检查业务禁用");
  570. // 检查是否禁用业务,做交易限制的检查
  571. TradeManageCodeEnum jobLimit = CModTools::get_mutable_instance().CheckJobLimited();
  572. DbgEx("ShowLimitScreen : TradeManageCodeEnum=%s", jobLimit._to_string());
  573. switch (jobLimit) {
  574. case TradeManageCodeEnum::Trade:
  575. CModTools::get_mutable_instance().killChromiumByName((+PAGE_TYPE::TradeManager)._to_string());
  576. break;
  577. case TradeManageCodeEnum::Disabled:
  578. {
  579. auto openRet = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::disabled,
  580. std::tuple < std::string, std::string>(m_sysInfo.strTerminalID.GetData(), generateTimeStr()));
  581. DbgEx("TradeManageCodeEnum Disabled, open page %s, %d", Error_Succeed == openRet.first ? "success" : "fail", openRet.second);
  582. }
  583. break;
  584. case TradeManageCodeEnum::JobUncomplete:
  585. {
  586. auto openRet = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::jobuncomplete,
  587. std::tuple < std::string, std::string>(m_sysInfo.strTerminalID.GetData(), generateTimeStr()));
  588. DbgEx("TradeManageCodeEnum JobUncomplete, open page %s, %d", Error_Succeed == openRet.first ? "success" : "fail", openRet.second);
  589. }
  590. break;
  591. default:
  592. break;
  593. }
  594. GetFunction()->ResetTimer(BROWSER_TIMER_ID, BROWSER_TIMER_INTERVAL);
  595. }
  596. #if (defined _WIN32 || defined _WIN64)
  597. void CChromiumEntity::OnCustomerCmd(const char* pszEntityName, DWORD dwMessageId, DWORD dwMessageSignature, IEBrowser::CustomerCmd& evt)
  598. {
  599. DbgEx("OnCustomerCmd %s", evt.cmdStr);
  600. }
  601. #endif
  602. void CChromiumEntity::generateCefclientTimer()
  603. {
  604. if (nullptr == m_pTimerListener)
  605. {
  606. m_pTimerListener = new TimerOutHelper<CChromiumEntity>(this, &CChromiumEntity::OnTaskTimerListener, NULL, false);
  607. GetFunction()->SetTimer(CHROMIUM_TIMER_ID, m_pTimerListener, 2000); //间隔执行时间
  608. }
  609. }
  610. void CChromiumEntity::generateBussinessLimitTimer() {
  611. DbgEx("Start BusinessLimitTimer");
  612. pBusinessLimitTimerListener = new TimerOutHelper<CChromiumEntity>(this, &CChromiumEntity::OnBusinessLimitTimerListener, NULL, false);
  613. GetFunction()->SetTimer(BROWSER_TIMER_ID, pBusinessLimitTimerListener, 5000);
  614. }
  615. int CChromiumEntity::getBrowserStartTimes() {
  616. CAutoArray<CSimpleStringA> t_names;
  617. CAutoArray<int> t_Idx;
  618. CAutoArray<CEntityStartInfo> t_Infos;
  619. GetFunction()->GetAllEntityStartInfo(t_names, t_Idx, t_Infos);
  620. for (int i = 0; i < t_names.GetCount(); i++)
  621. {
  622. if (t_names[i] == GetEntityName())
  623. return t_Infos[i].startTimes;
  624. }
  625. return -1;
  626. }
  627. void CChromiumEntity::checkUrlStartTime() {
  628. std::string startTimeStr = boost::posix_time::to_iso_extended_string(boost::posix_time::microsec_clock::local_time());
  629. int pos = startTimeStr.find('T');
  630. startTimeStr.replace(pos, 1, std::string(" "));
  631. pos = startTimeStr.find('.');
  632. startTimeStr.replace(pos, 1, std::string(":"));
  633. auto urlStartTime = boost::posix_time::microsec_clock::universal_time();
  634. while (!m_firstStartMain.try_lock_for(boost::chrono::seconds(30)))
  635. Dbg("wait 30s, but slv did not start");
  636. auto urlEndTime = boost::posix_time::microsec_clock::universal_time();
  637. auto timeDuration = urlEndTime - urlStartTime;
  638. Dbg("slv start at %s, used %d ms", startTimeStr.c_str(), timeDuration.total_milliseconds());
  639. if (1 == getBrowserStartTimes())
  640. {
  641. auto generateAlarmJson = [](CSimpleString entityName, CSimpleString startTime, int cost) ->CSimpleString {
  642. return CSimpleString::Format("[{\"name\":\"%s\",\"time\":\"%s\",\"cost\":%d}]", entityName.GetData(), startTime.GetData(), cost);
  643. };
  644. LogWarn(Severity_Low, Error_Debug, LOG_TRACE_ENTITY_START_TIME, generateAlarmJson("slv", startTimeStr.c_str(), timeDuration.total_milliseconds()).GetData());
  645. }
  646. m_firstStartMain.unlock();
  647. };
  648. void CChromiumEntity::DoBrowserCacheClearJob()
  649. {
  650. LOG_FUNCTION();
  651. CSmartPointer<IConfigInfo> spConfig;
  652. ErrorCodeEnum err = GetFunction()->OpenConfig(Config_Run, spConfig);
  653. CSimpleStringA str(true);
  654. err = spConfig->ReadConfigValue("Browser", "CacheClear", str);
  655. if (str.Compare("true", true) == 0) {
  656. BOOL bSucc(FALSE);
  657. CSimpleStringA strCachePath;
  658. GetFunction()->GetPath("Temp", strCachePath);
  659. if (!strCachePath.IsNullOrEmpty()) {
  660. bSucc = TRUE;
  661. const char* cacheDirs[] = { "cefCache", "cefCache_Ad", "cefCache_breakdown", "cefCache_ErrNotify", "cefCache_main"
  662. , "UOSBrowser_Ad", "UOSBrowser_main" };
  663. for (int i = 0; i < array_size(cacheDirs); ++i) {
  664. CSimpleStringA strcefCachePath(strCachePath);
  665. strcefCachePath += SPLIT_SLASH_STR;
  666. strcefCachePath += cacheDirs[i];
  667. if (ExistsDirA(strcefCachePath)) {
  668. RemoveDirRecursiveA(strcefCachePath);
  669. LogWarn(Severity_Middle, Error_Debug, LOG_EVT_CHROMIUM_BROWSER_CACHE_CLEAER,
  670. CSimpleStringA::Format("clear chromium browser cache: %s", strcefCachePath.GetData()));
  671. }
  672. }
  673. }
  674. if (bSucc) {
  675. spConfig->WriteConfigValue("Browser", "CacheClear", NULL);
  676. }
  677. }
  678. }
  679. void CChromiumEntity::OnTaskTimerListener(void* pData)
  680. {
  681. static int max_restartTime = 3;
  682. DbgEx("OnTaskTimerListener");
  683. if (max_restartTime == 0)
  684. {
  685. DbgEx("max_restartTime == 0, do not restart chromium");
  686. GetFunction()->KillTimer(CHROMIUM_TIMER_ID);
  687. return;
  688. }
  689. static bool t_firstStartMain = true;
  690. if (t_firstStartMain)
  691. {
  692. t_firstStartMain = false;
  693. m_firstStartMain.lock();
  694. boost::thread(boost::bind(&CChromiumEntity::checkUrlStartTime, this)).detach();
  695. }
  696. auto rc = CModTools::get_mutable_instance().StartChromiumBrowser();
  697. max_restartTime--;
  698. DbgEx("TaskTimerListen, startChromiumBrowser, rc:%d, pid:%d", rc.first, rc.second);
  699. if (0 == rc.first)
  700. GetFunction()->KillTimer(CHROMIUM_TIMER_ID);
  701. #if (defined _WIN32 || defined _WIN64)
  702. if (rc.first == Error_Succeed && rc.second != 0)
  703. {
  704. HANDLE defaultProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, rc.second);
  705. if (defaultProcess == nullptr)
  706. {
  707. DbgEx("OnTaskTimerListener, openProcess failed");
  708. return;
  709. }
  710. auto ret = assigntoJob(defaultProcess, rc.second);
  711. if (!ret.first)
  712. DbgEx("OnTaskTimerListener, assigntoJob failed");
  713. else
  714. {
  715. auto monitorThread = [&](HANDLE job, HANDLE process) {
  716. while (1)
  717. {
  718. if (WaitForSingleObject(process, 10) != WAIT_OBJECT_0) //process end
  719. DbgEx("default cefclient.exe job:%d, process:%d checkOpen", job, process);
  720. else
  721. {
  722. DbgEx("default cefclient.exe job:%d, process:%d check Closed, try to restart", job, process);
  723. TerminateJobObject(job, 0);
  724. max_restartTime--;
  725. generateCefclientTimer();
  726. break;
  727. }
  728. boost::this_thread::sleep_for(boost::chrono::seconds(10));
  729. }
  730. };
  731. if (ret.second != nullptr && defaultProcess != nullptr)
  732. boost::thread(monitorThread, ret.second, defaultProcess).detach();
  733. }
  734. }
  735. if (Error_Succeed != rc.first)
  736. {
  737. DbgEx("OnTaskTimerListener will be called after %d secs, rest restart time %d", 15, max_restartTime);
  738. if (max_restartTime)
  739. GetFunction()->ResetTimer(CHROMIUM_TIMER_ID, 15000);
  740. }
  741. else {
  742. DbgEx("OnTaskTimerListener rc = succeed");
  743. GetFunction()->KillTimer(CHROMIUM_TIMER_ID);
  744. }
  745. #endif
  746. }
  747. SP_BEGIN_ENTITY_MAP()
  748. SP_ENTITY(CChromiumEntity)
  749. SP_END_ENTITY_MAP()
  750. }