mod_chromium.cpp 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965
  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. #endif
  10. #include "fileutil.h"
  11. #include "baseEx.h"
  12. #include "CWebsocketServer.h"
  13. #include "mod_chromium.h"
  14. #include "base64.h"
  15. #include "CModTools.h"
  16. #include "cJSON.h"
  17. #include "SpIni.h"
  18. #include "CSocketClient.h"
  19. #include "processControl.h"
  20. #include <boost/chrono.hpp>
  21. #include <boost/bind.hpp>
  22. #include "../mod_upload/Upload_client_g.h"
  23. #include <tuple>
  24. #include <string>
  25. #include <algorithm>
  26. #include "EventCode.h"
  27. #ifdef OPEN_PERF
  28. #include <gperftools/profiler.h>
  29. #endif // OPEN_PERF
  30. #include <boost/date_time/posix_time/posix_time.hpp>
  31. #include "../mod_CameraConfigManage/Event.h"
  32. #include "../mod_ResourceWatcher/ResourceWatcher_msg_g.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. #if (defined _WIN32 || defined _WIN64)
  142. CModTools::get_mutable_instance().InitCModTools(this);
  143. //CModTools::get_mutable_instance().killAllChromium();
  144. //shell启动过程,已经进行了cef的kill操作。这里可能会把启动时间延长很多
  145. #else
  146. FetchCustomMainUrl(strArgs);
  147. CModTools::get_mutable_instance().InitCModTools(this);
  148. CModTools::get_mutable_instance().killAllChromium();
  149. DoBrowserCacheClearJob();
  150. #endif
  151. #if (defined _WIN32 || defined _WIN64)
  152. #else
  153. CSimpleStringA strDbgPath;
  154. GetFunction()->GetPath("Dbg", strDbgPath);
  155. set_traceback_path(strDbgPath.GetData());
  156. boost::thread([]() {
  157. for (auto i = 1; i < 28; i++)
  158. {
  159. if (SIGTERM == i)
  160. signal(i, [](int signum)->void {
  161. DbgEx("receive signal:%d, closeChromium", signum);
  162. CModTools::get_mutable_instance().killAllChromiumByThread(3);
  163. CWebsocketServer::stopServer();
  164. signal(signum, SIG_DFL);
  165. raise(signum);
  166. });
  167. else if (SIGSEGV == i || SIGABRT == i)
  168. signal(i, &seg_signal_handler);
  169. else if (SIGPROF == i || SIGALRM == i || SIGVTALRM == i)
  170. continue;
  171. else
  172. signal(i, &normal_signal_handle);
  173. }
  174. }).detach();
  175. #endif
  176. #if (defined _WIN32 || defined _WIN64)
  177. const int ArgsCount = strArgs.GetCount();
  178. LOG_TRACE("strArgs.GetCount() = %d", ArgsCount);
  179. for (int i = 0; i < ArgsCount; ++i) {
  180. DbgEx("strArgs[%d] = %s", i, strArgs[i].GetData());
  181. }
  182. if (ArgsCount == 1) {
  183. m_strCustomMainUrl = strArgs[0];
  184. DbgEx("Get custom main ulr: %s", m_strCustomMainUrl.GetData());
  185. }
  186. else if (ArgsCount == 2)
  187. {
  188. m_strCustomMainUrl = strArgs[0];
  189. m_strCustomAdUrl = strArgs[1];
  190. DbgEx("Get custom main url: %s, ad url: %s", m_strCustomMainUrl.GetData(), m_strCustomAdUrl.GetData());
  191. }
  192. #endif
  193. GetFunction()->GetSystemStaticInfo(m_sysInfo);
  194. if (!IsConfigMode()) {
  195. CSmartPointer<IConfigInfo> spConfig;
  196. if (Error_Succeed == GetFunction()->OpenConfig(Config_CenterSetting, spConfig))//特别坑,这个OpenConfig返回一直都是success
  197. {
  198. auto webMaskKey = CSimpleString::Format("WebMask_%s", m_sysInfo.strMachineType.GetData());
  199. CSimpleString webMaskStr;
  200. if (Error_Succeed == spConfig->ReadConfigValue("Chromium", webMaskKey.GetData(), webMaskStr))
  201. {
  202. auto maskArr = webMaskStr.Split('|');
  203. for (int i = 0; i < maskArr.GetCount(); i++)
  204. {
  205. auto trimStr = maskArr[i].Trim();
  206. if (!trimStr.Compare("ad", true))
  207. m_runAd = true;
  208. else if (!trimStr.Compare("main", true))
  209. m_runMain = true;
  210. else if (!trimStr.Compare("extend", true))
  211. m_runExtend = true;
  212. else if (!trimStr.Compare("login", true))
  213. m_runLogin = true;
  214. else if (!trimStr.Compare("with_browser", true))
  215. m_withBrowser = true;
  216. else if (!trimStr.Compare("with_min", true))
  217. m_withMin = true;
  218. else if (!trimStr.Compare("with_close", true))
  219. m_withClose = true;
  220. }
  221. #if (defined _WIN32 || defined _WIN64)
  222. #else
  223. m_runAd = m_runMain = true;
  224. m_runExtend = m_runLogin = m_withBrowser = m_withMin = m_withClose = false;
  225. #endif
  226. 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",
  227. m_sysInfo.strMachineType.GetData(), webMaskKey.GetData(), webMaskStr.GetData(), m_runAd, m_runMain, m_runExtend, m_runLogin, m_withBrowser
  228. ,m_withMin, m_withClose);
  229. if (m_withMin)
  230. CModTools::get_mutable_instance().setWithMin(m_withMin);
  231. if (m_withClose)
  232. CModTools::get_mutable_instance().setWithClose(m_withClose);
  233. }
  234. else
  235. DbgEx("can not find %s, use default", webMaskKey.GetData());
  236. }
  237. if (!m_runAd && !m_runMain && !m_runExtend && !m_withBrowser)
  238. {
  239. DbgEx("can not open centerSetting, maybe fault");
  240. /*
  241. if (!(m_sysInfo.strMachineType.IsEndWith("PAD", true) || m_sysInfo.strMachineType.IsEndWith("Stand2S", true)))
  242. {
  243. m_withBrowser = true;
  244. DbgEx("since is %s, so m_withBrowser:%d", m_sysInfo.strMachineType.GetData(), m_withBrowser);
  245. }
  246. */
  247. }
  248. #if (defined _WIN32 || defined _WIN64)
  249. if (!logProducer)
  250. logProducer = create_log_producer_storage("cefclient_logger", "0", "");
  251. #else
  252. CSimpleString dbgPath;
  253. GetFunction()->GetPath("Dbg", dbgPath);
  254. std::string dstDbgPath = dbgPath.GetData();
  255. dstDbgPath.append(SPLIT_SLASH_STR).append("mod_chromium");
  256. if (InitFileLogger(dstDbgPath))
  257. DbgToFileLogger("================");
  258. else
  259. DbgEx("[ERROR]logger init failed!");
  260. #endif
  261. CSimpleString translatePath;
  262. GetFunction()->GetPath("Cfg", translatePath);
  263. translatePath.Append(CSimpleStringA(SPLIT_SLASH_STR) + "UserCodeToMsgTip.ini");
  264. InitTranslateFile(translatePath.GetData());
  265. std::string magicStr = CModTools::get_mutable_instance().getMagicStr();
  266. boost::thread(boost::bind(SaveCefclientLog, magicStr)).detach();
  267. }
  268. }
  269. bool CChromiumEntity::OnPreStart_socketStart(CAutoArray<CSimpleStringA>& strArgs, CSmartPointer<ITransactionContext>& pTransactionContext)
  270. {
  271. ErrorCodeEnum Error;
  272. if (Error_Succeed != (Error = GetFunction()->StartTcpBridgeServer(m_iTcpBridgePort)))
  273. {
  274. DbgEx("start tcp bridge server failed!");
  275. pTransactionContext->SendAnswer(Error);
  276. return false;
  277. }
  278. // load all struct define xml & start websocket server
  279. CSimpleStringA strStructPath;
  280. GetFunction()->GetPath("Base", strStructPath);
  281. strStructPath.Append(CSimpleStringA(SPLIT_SLASH_STR) + "res" + SPLIT_SLASH_STR + "StructConfig" + SPLIT_SLASH_STR);
  282. DbgEx("find struct config files in path %s", strStructPath.GetData());
  283. m_pWsServer = new CWebsocketServer(strStructPath, this);
  284. m_pWsServer->run();
  285. return true;
  286. }
  287. bool CChromiumEntity::OnPreStart_register(CAutoArray<CSimpleStringA>& strArgs, CSmartPointer<ITransactionContext>& pTransactionContext)
  288. {
  289. ErrorCodeEnum Error;
  290. //与browser进行交互所必须,移除browser的机型不需要订阅browser相关
  291. if (m_withBrowser)
  292. {
  293. if (Error_Succeed != (Error = GetFunction()->SubscribeBroadcast("IEBrowser", "CustomerCmd", this, m_uidBrowserListenser))) {
  294. DbgEx("subscribe browser CustomerCmd failed!");
  295. pTransactionContext->SendAnswer(Error);
  296. }
  297. else
  298. DbgEx("subscribe browser CustomerCmd success!");
  299. if (Error_Succeed != (Error = GetFunction()->SubscribeLog(m_uidCameraListener, this, Log_Event, Severity_None, Error_IgnoreAll, -1, "CameraConfigManage")))
  300. DbgEx("subscribe Camera log failed!"); //非必须
  301. }
  302. if (!m_withBrowser)
  303. {//有browser的时候不需要订阅这一堆
  304. DbgEx("subscribe AccessAuthorization %s, %d",
  305. Error_Succeed == (Error = GetFunction()->SubscribeLog(m_uuidAccessAuth, this, Log_Event, Severity_None, Error_IgnoreAll, -1, "AccessAuthorization")) ? "success" : "failed", Error);
  306. DbgEx("subscribe ResourceWatcher %s, %d",
  307. Error_Succeed == (Error = GetFunction()->SubscribeBroadcast("ResourceWatcher", NULL, this, m_uuidResourceWatch)) ? "success" : "failed", Error);
  308. if (Error_Succeed != GetFunction()->RegistSysVarEvent("UIState", this))
  309. DbgEx("RegistSysVarEvent UIState failed!");
  310. if (Error_Succeed != GetFunction()->RegistSysVarEvent("TerminalStage", this))
  311. DbgEx("RegistSysVarEvent TerminalStage failed!");
  312. if (Error_Succeed != GetFunction()->RegistSysVarEvent("EntryPermit", this))
  313. DbgEx("RegistSysVarEvent EntryPermit failed!");
  314. if (Error_Succeed != GetFunction()->RegistSysVarEvent("SessionID", this))
  315. DbgEx("RegistSysVarEvent SessionID failed!");
  316. if (Error_Succeed != GetFunction()->RegistSysVarEvent("CustomerID", this))
  317. DbgEx("RegistSysVarEvent CustomerID failed!");
  318. if (Error_Succeed != GetFunction()->RegistSysVarEvent("CardStoreInUse", this))
  319. DbgEx("RegistSysVarEvent CardStoreInUse failed!");
  320. }
  321. #if (defined _WIN32 || defined _WIN64)
  322. //未定义Log_Notify
  323. #else
  324. Error = GetFunction()->SubscribeLog(m_uuidAllFault, this, Log_Notify, Severity_High, Error_IgnoreAll, -2, NULL, false);
  325. if (Error_Succeed == Error) {
  326. this->GetFunction()->GetPrivilegeFunction()->RefreshFrameworkState(FrameworkState_NotDisturb);
  327. }
  328. else {
  329. DbgEx("subscribe log for notify failed! %s", SpStrError(Error));
  330. }
  331. #endif
  332. return true;
  333. }
  334. bool CChromiumEntity::OnPreStart_openWeb()
  335. {
  336. //generateBussinessLimitTimer();
  337. #if (defined _WIN32 || defined _WIN64)
  338. if (strArgs.GetCount())
  339. {
  340. if (!m_strCustomMainUrl.IsNullOrEmpty())
  341. openMainPage();
  342. if (!m_strCustomAdUrl.IsNullOrEmpty())
  343. openAdPage();
  344. return true;
  345. }
  346. #endif
  347. if (m_runExtend) openExtendPage();
  348. if (m_runMain)
  349. {
  350. CSimpleStringA t_EntryPermit, t_terminalState;
  351. GetFunction()->GetSysVar("EntryPermit", t_EntryPermit);
  352. GetFunction()->GetSysVar("TerminalStage", t_terminalState);
  353. /** Z开头标识终端配种模式 [Gifur@20211017]*/
  354. if ('A' != t_terminalState[0] && 'Z' != t_terminalState[0])
  355. {
  356. if ('X' == t_terminalState[0])
  357. {
  358. DbgEx("do not begin accessAuth, terminalStage X, do nothing.");
  359. }
  360. else if (!m_withBrowser)
  361. {
  362. auto openRet = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::breakdown,
  363. std::tuple <std::string, std::string>(m_sysInfo.strTerminalID.GetData(), generateTimeStr()));
  364. DbgEx("access failed, open page breakdown %s, %d", Error_Succeed == openRet.first ? "success" : "fail", openRet.second);
  365. }
  366. }
  367. else
  368. {
  369. if (m_runAd) openAdPage();
  370. openMainPage();
  371. }
  372. }
  373. return true;
  374. }
  375. void CChromiumEntity::openMainPage()
  376. {
  377. #if (defined _WIN32 || defined _WIN64)
  378. generateCefclientTimer();
  379. #else
  380. CSystemRunInfo sysruninfo;
  381. GetFunction()->GetSystemRunInfo(sysruninfo);
  382. if (!(sysruninfo.dwBootOption & SystemBootOptionEnum::BootOption_Test))
  383. generateCefclientTimer();//非--test时,才会打开浏览器
  384. #endif
  385. }
  386. void CChromiumEntity::openAdPage()
  387. {
  388. auto openRet = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::Ad);
  389. DbgEx("open page Ad %s, pid:%d", Error_Succeed == openRet.first ? "success" : "fail", openRet.second);
  390. }
  391. void CChromiumEntity::openExtendPage()
  392. {
  393. auto openRet = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::extend);
  394. DbgEx("open page extend %s, pid:%d", Error_Succeed == openRet.first ? "success" : "fail", openRet.second);
  395. }
  396. void CChromiumEntity::OnPreStart(CAutoArray<CSimpleStringA> strArgs, CSmartPointer<ITransactionContext> pTransactionContext)
  397. {
  398. OnPreStart_Init(strArgs, pTransactionContext);//初始化部分, perf ,killchromium, signal, get custom url
  399. if (!OnPreStart_socketStart(strArgs, pTransactionContext)) {//OnPreStart_socketStart()->new CWebsocketServer(strStructPath, this) 时间过长
  400. return;
  401. }
  402. if (!IsConfigMode()) {
  403. if (!OnPreStart_register(strArgs, pTransactionContext)) {
  404. return;
  405. }
  406. if (!OnPreStart_openWeb()) {
  407. return;
  408. }
  409. }
  410. pTransactionContext->SendAnswer(Error_Succeed);
  411. }
  412. bool CChromiumEntity::CheckIsCardStore() {
  413. return m_sysInfo.strMachineType.IsEndWith("CardStore", true) || m_sysInfo.strMachineType.IsEndWith("CardPrinter", true);
  414. }
  415. void CChromiumEntity::OnSysVarEvent(const char* pszKey, const char* pszValue, const char* pszOldValue, const char* pszEntityName)
  416. {
  417. DbgEx("OnSysVarEvent %s, old->new:%s->%s", pszKey, pszOldValue, pszValue);
  418. if ((strnicmp(pszKey, "UIState", strlen("UIState")) == 0))
  419. {
  420. if (strnicmp(pszValue, "M", strlen("M")) == 0)
  421. {
  422. static bool firstEnter = true;
  423. if (firstEnter)
  424. {
  425. firstEnter = false;
  426. DbgEx("first Enter main page");
  427. m_firstStartMain.unlock();
  428. LogWarn(Severity_Low, Error_Debug, LOG_SLV_CHROMIUM_OPENSUCCESS,
  429. CSimpleStringA::Format("Chromium Enter main page success, %s", CModTools::get_mutable_instance().getFultureUrl().GetData()));
  430. }
  431. GetFunction()->UnregistSysVarEvent("UIState");
  432. }
  433. }
  434. /** 该事件有变化才会触发错误页 [Gifur@2022324]*/
  435. else if (0 == CSimpleStringA("TerminalStage").Compare(pszKey, true))
  436. {
  437. if (0 == CSimpleStringA("A").Compare(pszValue, true))
  438. {
  439. if(CModTools::get_mutable_instance().IsConfigWork())//url正常时才关闭
  440. {
  441. CModTools::get_mutable_instance().StopChromiumBrowser(ERR_PAGE_REASON::breakdown);
  442. if (m_runAd) openAdPage();
  443. openMainPage();
  444. //DbgEx("UnregistSysVarEvent TerminalStage %s", Error_Succeed == GetFunction()->UnregistSysVarEvent("TerminalStage") ? "success" : "fail");
  445. }
  446. }
  447. else if (0 == CSimpleStringA("X").Compare(pszValue, true))
  448. DbgEx("TerminalStage X, do nothing.");
  449. else
  450. {
  451. if (!m_withBrowser)
  452. {
  453. CModTools::get_mutable_instance().StopChromiumBrowser(ERR_PAGE_REASON::main);
  454. auto openRet = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::breakdown,
  455. std::tuple < std::string, std::string>(m_sysInfo.strTerminalID.GetData(), generateTimeStr()));
  456. DbgEx("access failed, open page breakdown %s, %d", Error_Succeed == openRet.first ? "success" : "fail", openRet.second);
  457. }
  458. }
  459. }
  460. else if (0 == CSimpleStringA("CardStoreInUse").Compare(pszKey, true) && CheckIsCardStore())
  461. {
  462. if (0 == CSimpleStringA("Y").Compare(pszValue, true))
  463. {
  464. auto openRet = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::CardStoreIsBusy,
  465. std::tuple <std::string, std::string>(m_sysInfo.strTerminalID.GetData(), generateTimeStr()));
  466. DbgEx("CardStoreIsBusy, open page CardStoreIsBusy %s, %d", Error_Succeed == openRet.first ? "success" : "fail", openRet.second);
  467. }
  468. else
  469. CModTools::get_mutable_instance().StopChromiumBrowser(ERR_PAGE_REASON::CardStoreIsBusy);
  470. }
  471. }
  472. void CChromiumEntity::OnPreClose(EntityCloseCauseEnum eCloseCause, CSmartPointer<ITransactionContext> pTransactionContext)
  473. {
  474. exitClean();
  475. pTransactionContext->SendAnswer(Error_Succeed);
  476. }
  477. void CChromiumEntity::exitClean()
  478. {
  479. static bool isExit = false;
  480. if (!isExit)
  481. {
  482. isExit = true;
  483. CModTools::get_mutable_instance().killAllChromiumByThread(3);
  484. delete m_pWsServer;
  485. if (m_pTimerListener != NULL)
  486. {
  487. GetFunction()->KillTimer(CHROMIUM_TIMER_ID);
  488. delete m_pTimerListener;
  489. m_pTimerListener = NULL;
  490. }
  491. GetFunction()->UnsubscribeBroadcast("IEBrowser");
  492. }
  493. }
  494. /** 查看启动顺序发现集中配置实体启动在本实体之前,无法调用集中配置的接口,随将实现搬到这里来 [Gifur@2021124]*/
  495. void CChromiumEntity::FetchCustomMainUrl(CAutoArray<CSimpleStringA>& strArgs)
  496. {
  497. #if (defined _WIN32 || defined _WIN64)
  498. #else
  499. const int ArgsCount = strArgs.GetCount();
  500. LOG_TRACE("strArgs.GetCount() = %d", ArgsCount);
  501. for (int i = 0; i < ArgsCount; ++i) {
  502. DbgEx("strArgs[%d] = %s", i, strArgs[i].GetData());
  503. }
  504. if (ArgsCount == 1) {
  505. m_strCustomMainUrl = strArgs[0];
  506. DbgEx("Get custom main url: %s", m_strCustomMainUrl.GetData());
  507. if (!m_strCustomMainUrl.IsNullOrEmpty()) {
  508. LogWarn(Severity_Low, Error_Debug, LOG_EVT_CHROMIUM_DETECT_CUSTOM_FULTURE_URL_FROM_START,
  509. CSimpleStringA::Format("从模块入参获取自定义链接:%s", m_strCustomMainUrl.GetData()));
  510. }
  511. } else {
  512. CSmartPointer<IConfigInfo> pConfig;
  513. GetFunction()->OpenConfig(Config_Cache, pConfig);
  514. int cnt(0), currentUsing(0);
  515. pConfig->ReadConfigValueInt("CustomWebUrl", "Count", cnt);
  516. pConfig->ReadConfigValueInt("CustomWebUrl", "Current", currentUsing);
  517. if (cnt > 0 && currentUsing > 0) {
  518. CSimpleStringA strAdUrl(true);
  519. CSimpleStringA strSection = CSimpleStringA::Format("CustomWebUrl%d", currentUsing);
  520. pConfig->ReadConfigValue(strSection, "FultureUrl", m_strCustomMainUrl);
  521. pConfig->ReadConfigValue(strSection, "AdUrl", strAdUrl);
  522. if (!m_strCustomMainUrl.IsNullOrEmpty()) {
  523. LogWarn(Severity_Low, Error_Debug, LOG_EVT_CHROMIUM_DETECT_CUSTOM_FULTURE_URL_FROM_CONFIG,
  524. CSimpleStringA::Format("从本地维护桌面获取自定义链接:%s", m_strCustomMainUrl.GetData()));
  525. }
  526. }
  527. }
  528. #endif
  529. }
  530. void CChromiumEntity::OnLog(const CAutoArray<CUUID>& SubIDs, const CUUID nLogID, const LogTypeEnum eLogType, const SeverityLevelEnum eLevel,
  531. const DWORD dwSysError, const DWORD dwUserCode, const DWORD dwEntityInstanceID, const WORD wEntityDevelID,
  532. const CAutoArray<DWORD>& Param, const char* pszEntityName, const char* pszModuleName, const char* pszMessage, const linkContext& pLinkInfo)
  533. {
  534. DbgEx("OnLog %x from entity %s, msg : %s", dwUserCode, NULL == pszEntityName ? "" : pszEntityName, NULL == pszMessage ? "" : pszMessage);
  535. #if (defined _WIN32 || defined _WIN64)
  536. //No Log_Notify
  537. #else
  538. if (Log_Notify == eLogType)
  539. {
  540. try {
  541. cJSON* pJson = cJSON_Parse(pszMessage);
  542. auto notifyReason = cJSON_GetObjectItem(pJson, "reason")->valuestring;
  543. auto notifymsg = cJSON_GetObjectItem(pJson, "errmsg")->valuestring;
  544. auto notiryRebootTime = cJSON_GetObjectItem(pJson, "rebootTime")->valuestring;
  545. auto notifyPool = m_pWsServer->getNotifyPool();
  546. if (notifyPool.size() > 0)
  547. {
  548. for (auto it : notifyPool)
  549. {
  550. DbgEx("Log_Notify err, notifyPool to %d, %d", it.first, it.second);
  551. m_pWsServer->do_send_notifyMsg(it.first, it.second, notifyReason, notifymsg, notiryRebootTime, dwSysError, dwUserCode);
  552. }
  553. }
  554. else
  555. {
  556. auto openRet = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::ErrNotify, { m_sysInfo.strTerminalID.GetData(), generateTimeStr() }, { notifyReason, notifymsg, notiryRebootTime, dwSysError, dwUserCode });
  557. DbgEx("Log_Notify err, open page %s, %d", Error_Succeed == openRet.first ? "success" : "fail", openRet.second);
  558. }
  559. }
  560. catch (std::exception& e) {
  561. DbgEx("Log_Notify err, %s", e.what());
  562. }
  563. return;
  564. }
  565. #endif
  566. switch (dwUserCode)
  567. {
  568. case LOG_EVT_BEGIN_CAMERA_CONFIG://no use
  569. {
  570. auto openRet = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::CameraConfig,
  571. std::tuple < std::string, std::string>(m_sysInfo.strTerminalID.GetData(), generateTimeStr()));
  572. DbgEx("show Screen Camera config, open page cameraconfig %s, %d", Error_Succeed == openRet.first ? "success" : "fail", openRet.second);
  573. }
  574. break;
  575. case LOG_EVT_END_CAMERA_CONFIG://no use
  576. DbgEx("end show Screen Camera config, close page cameraconfig");
  577. CModTools::get_mutable_instance().killChromiumByName((+PAGE_TYPE::CameraConfig)._to_string());
  578. break;
  579. default:
  580. break;
  581. }
  582. }
  583. void CChromiumEntity::OnTerminalManage(const char* pszEntityName, DWORD dwMessageId, DWORD dwMessageSignature, HealthManager::TerminalManager& evt)
  584. {
  585. DbgEx("OnTerminalManage : evt.op = %d", evt.op);
  586. switch (evt.op)
  587. {
  588. case 0:
  589. GetFunction()->SetSysVar("TerminalManagerState", "L", true);
  590. {
  591. auto openRet = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::TerminalManagerOff,
  592. std::tuple < std::string, std::string>(m_sysInfo.strTerminalID.GetData(), generateTimeStr()));
  593. DbgEx("TerminalManagerState L, open page TerminalManagerOff %s, %d", Error_Succeed == openRet.first ? "success" : "fail", openRet.second);
  594. }
  595. break;
  596. case 1:
  597. GetFunction()->SetSysVar("TerminalManagerState", "N", true);
  598. {
  599. DbgEx("TerminalManagerState N, try close TerminalManager");
  600. CModTools::get_mutable_instance().killChromiumByName((+PAGE_TYPE::TerminalManager)._to_string());
  601. }
  602. break;
  603. case 2:
  604. GetFunction()->SetSysVar("TerminalManagerState", "K", true);
  605. {
  606. auto openRet = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::TerminalManagerKickOut,
  607. std::tuple < std::string, std::string>(m_sysInfo.strTerminalID.GetData(), generateTimeStr()));
  608. DbgEx("TerminalManagerState K, open page TerminalManagerKickOut %s, %d", Error_Succeed == openRet.first ? "success" : "fail", openRet.second);
  609. }
  610. break;
  611. case 99:
  612. GetFunction()->SetSysVar("TerminalManagerState", "N", true);
  613. {
  614. DbgEx("TerminalManagerState N, try close TerminalManager");
  615. CModTools::get_mutable_instance().killChromiumByName((+PAGE_TYPE::TerminalManager)._to_string());
  616. }
  617. break;
  618. default:
  619. break;
  620. }
  621. }
  622. void CChromiumEntity::OnBusinessLimitTimerListener(void* pData)
  623. {
  624. DbgEx("定时任务检查业务禁用");
  625. // 检查是否禁用业务,做交易限制的检查
  626. TradeManageCodeEnum jobLimit = CModTools::get_mutable_instance().CheckJobLimited();
  627. DbgEx("ShowLimitScreen : TradeManageCodeEnum=%s", jobLimit._to_string());
  628. switch (jobLimit) {
  629. case TradeManageCodeEnum::Trade:
  630. CModTools::get_mutable_instance().killChromiumByName((+PAGE_TYPE::TradeManager)._to_string());
  631. break;
  632. case TradeManageCodeEnum::Disabled:
  633. {
  634. auto openRet = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::disabled,
  635. std::tuple < std::string, std::string>(m_sysInfo.strTerminalID.GetData(), generateTimeStr()));
  636. DbgEx("TradeManageCodeEnum Disabled, open page %s, %d", Error_Succeed == openRet.first ? "success" : "fail", openRet.second);
  637. }
  638. break;
  639. case TradeManageCodeEnum::JobUncomplete:
  640. {
  641. auto openRet = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::jobuncomplete,
  642. std::tuple < std::string, std::string>(m_sysInfo.strTerminalID.GetData(), generateTimeStr()));
  643. DbgEx("TradeManageCodeEnum JobUncomplete, open page %s, %d", Error_Succeed == openRet.first ? "success" : "fail", openRet.second);
  644. }
  645. break;
  646. default:
  647. break;
  648. }
  649. GetFunction()->ResetTimer(BROWSER_TIMER_ID, BROWSER_TIMER_INTERVAL);
  650. }
  651. #if (defined _WIN32 || defined _WIN64)
  652. void CChromiumEntity::OnCustomerCmd(const char* pszEntityName, DWORD dwMessageId, DWORD dwMessageSignature, IEBrowser::CustomerCmd& evt)
  653. {
  654. DbgEx("OnCustomerCmd %s", evt.cmdStr);
  655. }
  656. #endif
  657. void CChromiumEntity::OnBrowserCacheClean(const char* pszEntityName, DWORD dwMessageId, DWORD dwMessageSignature, ResourceWatcher::BrowserCacheClean& evt)
  658. {
  659. DbgEx("OnOnBrowserCacheClean, needClean:%d", evt.needClean);
  660. ErrorCodeEnum error = Error_Succeed;
  661. if (!evt.needClean)
  662. return;
  663. CSimpleString tmpCacheDir;
  664. if (Error_Succeed != (error = GetFunction()->GetPath("Temp", tmpCacheDir)))
  665. {
  666. DbgEx("OnBrowserCacheClean get cache path err, %d", error);
  667. return;
  668. }
  669. #if (defined _WIN32 || defined _WIN64)
  670. CModTools::get_mutable_instance().lockGuard();
  671. CModTools::get_mutable_instance().StopChromiumBrowser(ERR_PAGE_REASON::breakdown, true);//close all tab
  672. auto tmpDirArr = find_files(tmpCacheDir.GetData(), "cefCache*", true);
  673. for each (auto it in tmpDirArr)
  674. {
  675. LogWarn(Severity_Low, Error_Debug, LOG_EVT_CHROMIUM_BROWSER_CACHE_CLEAER, CSimpleStringA::Format("clear chromium browser cache %s %s", it.c_str(),
  676. RemoveDirRecursive(it.c_str()) ? "success" : "fail"));
  677. }
  678. CModTools::get_mutable_instance().unlockGuard();
  679. #else
  680. //uos 由于无guard,需要重启整个chromium实体
  681. CModTools::get_mutable_instance().killAllChromium();
  682. auto tmpDirArr = find_files(tmpCacheDir.GetData(), "cefCache*", true);
  683. auto uosTmpDirArr = find_files(tmpCacheDir.GetData(), "UOSBrowser*", true);
  684. std::for_each(uosTmpDirArr.begin(), uosTmpDirArr.end(), [&](std::string tmp) {
  685. tmpDirArr.push_back(tmp);
  686. });//insert uosTmpDirArr into tmpDirArr
  687. for (auto it = tmpDirArr.begin(); it != tmpDirArr.end(); it++)
  688. LogWarn(Severity_Low, Error_Debug, LOG_EVT_CHROMIUM_BROWSER_CACHE_CLEAER, CSimpleStringA::Format("clear chromium browser cache %s %s", it->c_str(),
  689. RemoveDirRecursive(it->c_str()) ? "success" : "fail"));
  690. if (m_pTimerListener != NULL)
  691. {
  692. GetFunction()->KillTimer(CHROMIUM_TIMER_ID);
  693. delete m_pTimerListener;
  694. m_pTimerListener = NULL;
  695. }
  696. OnPreStart_openWeb();//重新调用open web
  697. #endif
  698. }
  699. void CChromiumEntity::generateCefclientTimer()
  700. {
  701. if (nullptr == m_pTimerListener)
  702. {
  703. m_pTimerListener = new TimerOutHelper<CChromiumEntity>(this, &CChromiumEntity::OnTaskTimerListener, NULL, false);
  704. GetFunction()->SetTimer(CHROMIUM_TIMER_ID, m_pTimerListener, 2000); //间隔执行时间
  705. }
  706. }
  707. void CChromiumEntity::generateBussinessLimitTimer() {
  708. DbgEx("Start BusinessLimitTimer");
  709. pBusinessLimitTimerListener = new TimerOutHelper<CChromiumEntity>(this, &CChromiumEntity::OnBusinessLimitTimerListener, NULL, false);
  710. GetFunction()->SetTimer(BROWSER_TIMER_ID, pBusinessLimitTimerListener, 5000);
  711. }
  712. int CChromiumEntity::getBrowserStartTimes() {
  713. CAutoArray<CSimpleStringA> t_names;
  714. CAutoArray<int> t_Idx;
  715. CAutoArray<CEntityStartInfo> t_Infos;
  716. GetFunction()->GetAllEntityStartInfo(t_names, t_Idx, t_Infos);
  717. for (int i = 0; i < t_names.GetCount(); i++)
  718. {
  719. if (t_names[i] == GetEntityName())
  720. return t_Infos[i].startTimes;
  721. }
  722. return -1;
  723. }
  724. void CChromiumEntity::checkUrlStartTime() {
  725. std::string startTimeStr = boost::posix_time::to_iso_extended_string(boost::posix_time::microsec_clock::local_time());
  726. int pos = startTimeStr.find('T');
  727. startTimeStr.replace(pos, 1, std::string(" "));
  728. pos = startTimeStr.find('.');
  729. startTimeStr.replace(pos, 1, std::string(":"));
  730. auto urlStartTime = boost::posix_time::microsec_clock::universal_time();
  731. while (!m_firstStartMain.try_lock_for(boost::chrono::seconds(30)))
  732. Dbg("wait 30s, but slv did not start");
  733. auto urlEndTime = boost::posix_time::microsec_clock::universal_time();
  734. auto timeDuration = urlEndTime - urlStartTime;
  735. Dbg("slv start at %s, used %d ms", startTimeStr.c_str(), timeDuration.total_milliseconds());
  736. if (1 == getBrowserStartTimes())
  737. {
  738. auto generateAlarmJson = [](CSimpleString entityName, CSimpleString startTime, int cost) ->CSimpleString {
  739. return CSimpleString::Format("[{\"name\":\"%s\",\"time\":\"%s\",\"cost\":%d}]", entityName.GetData(), startTime.GetData(), cost);
  740. };
  741. LogWarn(Severity_Low, Error_Debug, LOG_TRACE_ENTITY_START_TIME, generateAlarmJson("slv", startTimeStr.c_str(), timeDuration.total_milliseconds()).GetData());
  742. }
  743. m_firstStartMain.unlock();
  744. };
  745. void CChromiumEntity::DoBrowserCacheClearJob()
  746. {
  747. #if (defined _WIN32 || defined _WIN64)
  748. #else
  749. LOG_FUNCTION();
  750. CSmartPointer<IConfigInfo> spConfig;
  751. ErrorCodeEnum err = GetFunction()->OpenConfig(Config_Cache, spConfig);
  752. CSimpleStringA str(true);
  753. err = spConfig->ReadConfigValue("Browser", "CacheClear", str);
  754. if (str.Compare("true", true) == 0) {
  755. BOOL bSucc(FALSE);
  756. CSimpleStringA strCachePath;
  757. GetFunction()->GetPath("Temp", strCachePath);
  758. if (!strCachePath.IsNullOrEmpty()) {
  759. bSucc = TRUE;
  760. const char* cacheDirs[] = { "cefCache", "cefCache_Ad", "cefCache_breakdown","cefCache_ErrNotify", "cefCache_main"
  761. , "UOSBrowser_Ad", "UOSBrowser_main"
  762. , "UOSBrowserConfig_Ad", "UOSBrowserConfig_main"
  763. , "UOSBrowser2_Ad", "UOSBrowser2_main"
  764. , "UOSBrowserConfig2_Ad", "UOSBrowserConfig2_main" };
  765. const int cacheDirsLength = (5 + 4 + 4);
  766. for (int i = 0; i < cacheDirsLength; ++i) {
  767. CSimpleStringA strcefCachePath(strCachePath);
  768. strcefCachePath += SPLIT_SLASH_STR;
  769. strcefCachePath += cacheDirs[i];
  770. if (ExistsDirA(strcefCachePath)) {
  771. RemoveDirRecursiveA(strcefCachePath);
  772. LogWarn(Severity_Low, Error_Debug, LOG_EVT_CHROMIUM_BROWSER_CACHE_CLEAER,
  773. CSimpleStringA::Format("clear chromium browser cache: %s", strcefCachePath.GetData()));
  774. }
  775. }
  776. }
  777. if (bSucc) {
  778. spConfig->WriteConfigValue("Browser", "CacheClear", NULL);
  779. }
  780. }
  781. #endif
  782. }
  783. void CChromiumEntity::OnTaskTimerListener(void* pData)
  784. {
  785. static int max_restartTime = 3;
  786. DbgEx("OnTaskTimerListener");
  787. if (max_restartTime == 0)
  788. {
  789. DbgEx("max_restartTime == 0, do not restart chromium");
  790. GetFunction()->KillTimer(CHROMIUM_TIMER_ID);
  791. return;
  792. }
  793. static bool t_firstStartMain = true;
  794. if (t_firstStartMain)
  795. {
  796. t_firstStartMain = false;
  797. m_firstStartMain.lock();
  798. boost::thread(boost::bind(&CChromiumEntity::checkUrlStartTime, this)).detach();
  799. }
  800. auto rc = CModTools::get_mutable_instance().StartChromiumBrowser();
  801. max_restartTime--;
  802. DbgEx("TaskTimerListen, startChromiumBrowser, rc:%d, pid:%d", rc.first, rc.second);
  803. if (0 == rc.first)
  804. GetFunction()->KillTimer(CHROMIUM_TIMER_ID);
  805. #if (defined _WIN32 || defined _WIN64)
  806. if (rc.first == Error_Succeed && rc.second != 0)
  807. {
  808. HANDLE defaultProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, rc.second);
  809. if (defaultProcess == nullptr)
  810. {
  811. DbgEx("OnTaskTimerListener, openProcess failed");
  812. return;
  813. }
  814. auto ret = assigntoJob(defaultProcess, rc.second);
  815. if (!ret.first)
  816. DbgEx("OnTaskTimerListener, assigntoJob failed");
  817. else
  818. {
  819. auto monitorThread = [&](HANDLE job, HANDLE process) {
  820. while (1)
  821. {
  822. if (WaitForSingleObject(process, 10) != WAIT_OBJECT_0) //process end
  823. DbgEx("default cefclient.exe job:%d, process:%d checkOpen", job, process);
  824. else
  825. {
  826. DbgEx("default cefclient.exe job:%d, process:%d check Closed, try to restart", job, process);
  827. TerminateJobObject(job, 0);
  828. max_restartTime--;
  829. generateCefclientTimer();
  830. break;
  831. }
  832. boost::this_thread::sleep_for(boost::chrono::seconds(10));
  833. }
  834. };
  835. if (ret.second != nullptr && defaultProcess != nullptr)
  836. boost::thread(monitorThread, ret.second, defaultProcess).detach();
  837. }
  838. }
  839. if (Error_Succeed != rc.first)
  840. {
  841. DbgEx("OnTaskTimerListener will be called after %d secs, rest restart time %d", 15, max_restartTime);
  842. if (max_restartTime)
  843. GetFunction()->ResetTimer(CHROMIUM_TIMER_ID, 15000);
  844. }
  845. else {
  846. DbgEx("OnTaskTimerListener rc = succeed");
  847. GetFunction()->KillTimer(CHROMIUM_TIMER_ID);
  848. }
  849. #endif
  850. }
  851. SP_BEGIN_ENTITY_MAP()
  852. SP_ENTITY(CChromiumEntity)
  853. SP_END_ENTITY_MAP()
  854. }