mod_chromium.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550
  1. #if (defined _WIN32 || defined _WIN64)
  2. #include "stdafx.h"
  3. #include <Windows.h>
  4. #include <WinUser.h>
  5. #endif
  6. #include "baseEx.h"
  7. #include "CWebsocketServer.h"
  8. #include "mod_chromium.h"
  9. #include "base64.h"
  10. #include "CModTools.h"
  11. #include "cJSON.h"
  12. #include "SpIni.h"
  13. #include "CSocketClient.h"
  14. #include "processControl.h"
  15. #include <boost/chrono.hpp>
  16. #include <boost/bind.hpp>
  17. #include "path.h"
  18. #include "guitask/guitask.h"
  19. #include "EventCode.h"
  20. #include "../mod_upload/Upload_client_g.h"
  21. #define COMPKEY_TERMINATE ((UINT_PTR) 0)
  22. #define COMPKEY_STATUS ((UINT_PTR) 1)
  23. #define COMPKEY_JOBOBJECT ((UINT_PTR) 2)
  24. #define LOG_EVT_SELFCHECK_ASSISTANTCHANNEL_IDLE 0x50500001 //协助通道重启
  25. //#define EVENT_UKEY_PULLOUT 0x21000008 // 证书拔出 0x21000008 1 检测到维护证书拔出,用于驱动本地维护状态
  26. #define LOG_EVT_BEGIN_CAMERA_CONFIG 0x21D00001
  27. #define LOG_EVT_END_CAMERA_CONFIG 0x21D00002
  28. #define MSG_EVT_STARTACTIVECAPTURE 0x31400001 //开始主动活体
  29. #define MSG_EVT_STOPACTIVECAPTURE 0x31400002 //停止主动活体
  30. #define LOG_EVT_SHOWACTIVECAPTUREMSG 0x31400003 //显示主动活体提示消息
  31. #define CLIENT_MANAGER_PATH "c:\\Program Files\\CmbWinPad\\CmbWinPad.exe"
  32. namespace Chromium {
  33. CChromiumEntity::CChromiumEntity() :m_pWsServer(NULL), m_iTcpBridgePort(4504), m_pTimerListener(NULL), m_strCustomMainUrl(true)
  34. {
  35. DbgEx("CChromiumEntity constructor");
  36. boost::thread(boost::bind(&CChromiumEntity::CefClintNotify, this)).detach(); //后台自动运行
  37. }
  38. CChromiumEntity::~CChromiumEntity()
  39. {
  40. if (NULL != m_pWsServer)
  41. {
  42. free(m_pWsServer);
  43. m_pWsServer = NULL;
  44. }
  45. //DeleteCriticalSection(&g_csInvokFreeRDP);
  46. }
  47. #if (defined _WIN32 || defined _WIN64)
  48. void CChromiumEntity::JobNotify() {
  49. TCHAR sz[2000] = _T("");
  50. BOOL fDone = FALSE;
  51. while (!fDone) {
  52. DWORD dwBytesXferred;
  53. ULONG_PTR CompKey;
  54. LPOVERLAPPED po;
  55. GetQueuedCompletionStatus(m_hIOCP, &dwBytesXferred, &CompKey, &po, INFINITE);
  56. fDone = (CompKey == COMPKEY_TERMINATE);
  57. if (CompKey == COMPKEY_JOBOBJECT) {
  58. switch (dwBytesXferred) {
  59. case JOB_OBJECT_MSG_END_OF_JOB_TIME:
  60. Dbg("Job time limit reached");
  61. break;
  62. case JOB_OBJECT_MSG_END_OF_PROCESS_TIME:
  63. Dbg("Job process (Id=%d) time limit reached", po);
  64. break;
  65. case JOB_OBJECT_MSG_ACTIVE_PROCESS_LIMIT:
  66. Dbg("Too many active processes in job");
  67. break;
  68. case JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO:
  69. Dbg("Job contains no active processes");
  70. break;
  71. case JOB_OBJECT_MSG_NEW_PROCESS:
  72. Dbg("New process (Id=%d) in Job", po);
  73. break;
  74. case JOB_OBJECT_MSG_EXIT_PROCESS:
  75. Dbg("Process (Id=%d) terminated", po);
  76. break;
  77. case JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS:
  78. Dbg("Process (Id=%d) terminated abnormally", po);
  79. break;
  80. case JOB_OBJECT_MSG_PROCESS_MEMORY_LIMIT:
  81. Dbg("Process (Id=%d) exceeded memory limit", po);
  82. break;
  83. case JOB_OBJECT_MSG_JOB_MEMORY_LIMIT:
  84. Dbg("Process (Id=%d) exceeded job memory limit", po);
  85. break;
  86. default:
  87. Dbg("Unknown notification: %d", dwBytesXferred);
  88. break;
  89. }
  90. CompKey = 1;
  91. }
  92. }
  93. }
  94. #endif
  95. void CChromiumEntity::OnPreStart(CAutoArray<CSimpleStringA> strArgs, CSmartPointer<ITransactionContext> pTransactionContext)
  96. {
  97. GetFunction()->GetSystemStaticInfo(m_sysInfo);
  98. ErrorCodeEnum Error;
  99. Error = GetFunction()->StartTcpBridgeServer(m_iTcpBridgePort);
  100. #if (defined _WIN32 || defined _WIN64)
  101. Error = GetFunction()->SubscribeBroadcast("IEBrowser", "CustomerCmd", this, m_uidBrowserListenser);
  102. if (Error != Error_Succeed) {
  103. LOG_TRACE("subscribe browser CustomerCmd failed!");
  104. pTransactionContext->SendAnswer(Error);
  105. }
  106. else
  107. LOG_TRACE("subscribe browser CustomerCmd success!");
  108. #endif
  109. if (Error != Error_Succeed)
  110. {
  111. LOG_TRACE("start tcp bridge server failed!");
  112. pTransactionContext->SendAnswer(Error);
  113. return;
  114. }
  115. const int ArgsCount = strArgs.GetCount();
  116. LOG_TRACE("strArgs.GetCount() = %d", ArgsCount);
  117. for (int i = 0; i < ArgsCount; ++i) {
  118. Dbg("strArgs[%d] = %s", i, strArgs[i].GetData());
  119. }
  120. if(ArgsCount == 1) {
  121. m_strCustomMainUrl = strArgs[0];
  122. Dbg("Get custom main ulr: %s", m_strCustomMainUrl.GetData());
  123. }
  124. CModTools::get_mutable_instance().InitCModTools(this);
  125. CModTools::get_mutable_instance().killAllChromium();
  126. // load all struct define xml & start websocket server
  127. CSimpleStringA strStructPath;
  128. GetFunction()->GetPath("Base", strStructPath);
  129. strStructPath.Append(CSimpleStringA(SPLIT_SLASH_STR) + "res" + SPLIT_SLASH_STR + "StructConfig" + SPLIT_SLASH_STR);
  130. DbgEx("find struct config files in path %s", strStructPath.GetData());
  131. m_pWsServer = new CWebsocketServer(strStructPath, this);
  132. m_pWsServer->run();
  133. try {
  134. chromiumRpcTask::get_mutable_instance().openrpcServer(DEFAULT_CHROMIUM_RPCPORT);
  135. DbgEx("start rpcTask in port %d", DEFAULT_CHROMIUM_RPCPORT);
  136. }
  137. catch (...) {
  138. DbgEx("open rpcTask failed");
  139. }
  140. /*低柜
  141. //LOG_EVT_BEGIN_CAMERA_CONFIG, LOG_EVT_END_CAMERA_CONFIG
  142. Error = GetFunction()->SubscribeLog(m_uidCameraListener, this, Log_Event, Severity_None, Error_IgnoreAll, -1, "CameraConfigManage");
  143. if (Error != Error_Succeed)
  144. LOG_TRACE("subscribe Camera log failed!"); //非必须
  145. */
  146. Error = GetFunction()->SubscribeLog(m_uuidAccessAuth, this, Log_Event, Severity_None, Error_IgnoreAll, -1, "AccessAuthorization");
  147. if (Error != Error_Succeed)
  148. LOG_TRACE("subscribe AccessAuthorization log failed!");
  149. else
  150. LOG_TRACE("subscribe AccessAuthorization success!");
  151. GetFunction()->SubscribeLog(m_uuidAccessAuthErr, this, Log_Error, Severity_None, Error_IgnoreAll, -1, "AccessAuthorization");
  152. GetFunction()->RegistSysVarEvent("UIState", this);
  153. GetFunction()->RegistSysVarEvent("EntryPermit", this);
  154. generateBussinessLimitTimer();
  155. // 按照单屏方式
  156. pTransactionContext->SendAnswer(Error_Succeed);
  157. }
  158. void CChromiumEntity::OnSysVarEvent(const char* pszKey, const char* pszValue, const char* pszOldValue, const char* pszEntityName)
  159. {
  160. Dbg("OnSysVarEvent %s, old->new:%s->%s", pszKey, pszOldValue, pszValue);
  161. if ((strnicmp(pszKey, "UIState", strlen("UIState")) == 0))
  162. {
  163. if (strnicmp(pszValue, "M", strlen("M")) == 0)
  164. {
  165. static bool firstEnter = true;
  166. if (firstEnter)
  167. {
  168. firstEnter = false;
  169. Dbg("first Enter main page");
  170. }
  171. }
  172. }
  173. }
  174. void CChromiumEntity::OnPreClose(EntityCloseCauseEnum eCloseCause, CSmartPointer<ITransactionContext> pTransactionContext)
  175. {
  176. if (m_pTimerListener != NULL)
  177. {
  178. GetFunction()->KillTimer(CHROMIUM_TIMER_ID);
  179. delete m_pTimerListener;
  180. m_pTimerListener = NULL;
  181. }
  182. GetFunction()->UnsubscribeBroadcast("IEBrowser");
  183. pTransactionContext->SendAnswer(Error_Succeed);
  184. }
  185. void CChromiumEntity::OnLog(const CAutoArray<CUUID>& SubIDs, const CUUID nLogID, const LogTypeEnum eLogType, const SeverityLevelEnum eLevel,
  186. const DWORD dwSysError, const DWORD dwUserCode, const DWORD dwEntityInstanceID, const WORD wEntityDevelID,
  187. const CAutoArray<DWORD>& Param, const char* pszEntityName, const char* pszModuleName, const char* pszMessage)
  188. {
  189. Dbg("OnLog %x", dwUserCode);
  190. switch (dwUserCode)
  191. {
  192. case LOG_EVT_BEGIN_CAMERA_CONFIG://no use
  193. {
  194. auto openRet = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::CameraConfig);
  195. Dbg("show Screen Camera config, open page cameraconfig, %d", openRet.first);
  196. }
  197. break;
  198. case LOG_EVT_END_CAMERA_CONFIG://no use
  199. Dbg("end show Screen Camera config, close page cameraconfig");
  200. CModTools::get_mutable_instance().killChromiumByName((+PAGE_TYPE::CameraConfig)._to_string());
  201. break;
  202. case EVENT_ACCESSAUTH_SUCCEED:
  203. Dbg("access auth success, open page mainurl");
  204. {
  205. CSystemRunInfo sysruninfo;
  206. GetFunction()->GetSystemRunInfo(sysruninfo);
  207. if (!(sysruninfo.dwBootOption & SystemBootOptionEnum::BootOption_Test))
  208. generateCefclientTimer();//非--test时,才会打开浏览器
  209. }
  210. break;
  211. case EVENT_ACCESSAUTH_FAILED:
  212. case EVENT_ACCESSAUTH_TIMEOUT:
  213. {
  214. auto openRet = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::breakdown);
  215. Dbg("access failed, open page breakdown, %d", openRet.first);
  216. }
  217. break;
  218. default:
  219. break;
  220. }
  221. }
  222. void CChromiumEntity::OnTerminalManage(const char* pszEntityName, DWORD dwMessageId, DWORD dwMessageSignature, HealthManager::TerminalManager& evt)
  223. {
  224. Dbg("OnTerminalManage : evt.op = %d", evt.op);
  225. switch (evt.op)
  226. {
  227. case 0:
  228. GetFunction()->SetSysVar("TerminalManagerState", "L", true);
  229. {
  230. auto openRet = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::TerminalManagerOff);
  231. Dbg("TerminalManagerState L, open page TerminalManagerOff, %d", openRet.first);
  232. }
  233. break;
  234. case 1:
  235. GetFunction()->SetSysVar("TerminalManagerState", "N", true);
  236. {
  237. Dbg("TerminalManagerState N, try close TerminalManager");
  238. CModTools::get_mutable_instance().killChromiumByName((+PAGE_TYPE::TerminalManager)._to_string());
  239. }
  240. break;
  241. case 2:
  242. GetFunction()->SetSysVar("TerminalManagerState", "K", true);
  243. {
  244. auto openRet = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::TerminalManagerKickOut);
  245. Dbg("TerminalManagerState K, open page TerminalManagerKickOut, %d", openRet.first);
  246. }
  247. break;
  248. case 99:
  249. GetFunction()->SetSysVar("TerminalManagerState", "N", true);
  250. {
  251. Dbg("TerminalManagerState N, try close TerminalManager");
  252. CModTools::get_mutable_instance().killChromiumByName((+PAGE_TYPE::TerminalManager)._to_string());
  253. }
  254. break;
  255. default:
  256. break;
  257. }
  258. }
  259. void CChromiumEntity::OnBusinessLimitTimerListener(void* pData)
  260. {
  261. Dbg("定时任务检查业务禁用");
  262. // 检查是否禁用业务,做交易限制的检查
  263. TradeManageCodeEnum jobLimit = CModTools::get_mutable_instance().CheckJobLimited();
  264. Dbg("ShowLimitScreen : TradeManageCodeEnum=%s", jobLimit._to_string());
  265. switch (jobLimit) {
  266. case TradeManageCodeEnum::Trade:
  267. CModTools::get_mutable_instance().killChromiumByName((+PAGE_TYPE::TradeManager)._to_string());
  268. break;
  269. case TradeManageCodeEnum::Disabled:
  270. {
  271. auto openRet = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::disabled);
  272. Dbg("TradeManageCodeEnum Disabled, open page %d", openRet.first);
  273. }
  274. break;
  275. case TradeManageCodeEnum::JobUncomplete:
  276. {
  277. auto openRet = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::jobuncomplete);
  278. Dbg("TradeManageCodeEnum JobUncomplete, open page %d", openRet.first);
  279. }
  280. break;
  281. default:
  282. break;
  283. }
  284. GetFunction()->ResetTimer(BROWSER_TIMER_ID, BROWSER_TIMER_INTERVAL);
  285. }
  286. void CChromiumEntity::CefClintNotify()
  287. {
  288. #if(defined _WIN32 || defined _WIN64)
  289. while (1)
  290. {
  291. for (auto it = m_cefArr.begin(); it != m_cefArr.end(); it++)
  292. {
  293. if (WaitForSingleObject(std::get<1>(it->second), 10) != WAIT_OBJECT_0) //process end
  294. DbgEx("cefclient.exe tag:%s job:%d, process:%d checkOpen", it->first.c_str(), std::get<0>(it->second), std::get<1>(it->second));
  295. else
  296. {
  297. DbgEx("cefclient.exe tag:%s job:%d, process:%d check Closed, try to restart", it->first.c_str(), std::get<0>(it->second), std::get<1>(it->second));
  298. auto info = it->first;
  299. auto cmdline = std::get<2>(it->second);//save the param
  300. TerminateJobObject(std::get<0>(it->second), 0);
  301. m_cefArr.erase(it->first);
  302. auto startRet = startProcessInJob(cmdline, "");
  303. if (std::get<0>(startRet))
  304. m_cefArr.insert(std::make_pair(info, std::make_tuple(std::get<1>(startRet), std::get<2>(startRet), cmdline)));
  305. break;
  306. }
  307. }
  308. boost::this_thread::sleep_for(boost::chrono::seconds(10));
  309. }
  310. #endif
  311. }
  312. #if (defined _WIN32 || defined _WIN64)
  313. void CChromiumEntity::OnCustomerCmd(const char* pszEntityName, DWORD dwMessageId, DWORD dwMessageSignature, IEBrowser::CustomerCmd& evt)
  314. {
  315. DbgEx("OnCustomerCmd %s", evt.cmdStr);
  316. static std::pair<int, std::string> historyChromium;
  317. auto jsDeletor = [](cJSON* p) {
  318. cJSON_Delete(p);
  319. };
  320. std::unique_ptr<cJSON, decltype(jsDeletor)> cmdJs(cJSON_Parse(evt.cmdStr), jsDeletor);
  321. auto cmdStr = cJSON_GetObjectItem(cmdJs.get(), "command")->valuestring;
  322. auto chromiumCLoseInJob = [&](std::string closeJob) -> bool {
  323. auto it = m_cefArr.find(closeJob);
  324. if (m_cefArr.end() != it)
  325. {
  326. TerminateJobObject(std::get<0>(it->second), 0);
  327. m_cefArr.erase(closeJob);
  328. return true;
  329. }
  330. else
  331. {
  332. DbgEx("m_cefArr can not find %s", closeJob.c_str());
  333. return false;
  334. }
  335. };
  336. if (!strcmp(cmdStr, "ChromiumStart"))
  337. {
  338. auto info = cJSON_GetObjectItem(cmdJs.get(), "info")->valuestring;
  339. auto fullscreen = cJSON_GetObjectItem(cmdJs.get(), "fullscreen")->valueint;
  340. auto top = cJSON_GetObjectItem(cmdJs.get(), "top")->valueint;
  341. // 感觉应当通过FreeRDP来启动Chromium,不应该自己管理
  342. // 需要保存启动的chromium的句柄值或者进程Id,通过该进程Id来获取句柄管理chromium运行
  343. // 因为有多个chromium,此时对每一个H5页面,都保存连接。并无法感知到某一个chromium的连接都不存在来重启chromium
  344. chromiumCLoseInJob(info);
  345. CSmartPointer<IConfigInfo> spCerConfig;
  346. GetFunction()->OpenConfig(Config_CenterSetting, spCerConfig);
  347. CSimpleString UserMgrUrlFulture;
  348. SpIniMappingTable table;
  349. // clean cache every time
  350. table.AddEntryString(GetEntityName(), "UserMgrUrlFulture", UserMgrUrlFulture, "");
  351. if (Error_Succeed != table.Load(spCerConfig))
  352. {
  353. DbgEx("load UserMgrUrlFulture failed");
  354. return;
  355. }
  356. CSimpleStringA strChromiumPath;
  357. GetFunction()->GetPath("Base", strChromiumPath);
  358. strChromiumPath.Append("\\bin\\Chromium\\");
  359. auto checkHttpThread = boost::async(boost::bind(checkHttpThreadFun, UserMgrUrlFulture.GetData()));
  360. checkHttpThread.wait_for(boost::chrono::seconds(1));
  361. Dbg("%s http check %s", UserMgrUrlFulture.GetData(), (checkHttpThread.is_ready() && checkHttpThread.get()) ? "sucess" : "failed");
  362. CSimpleStringA cachePath;
  363. GetFunction()->GetPath("Temp", cachePath);
  364. cachePath.Append("\\cefCache");
  365. CSimpleStringA strCmdLine = "";
  366. strCmdLine.Append(strChromiumPath).Append("cefclient.exe --url=").Append(UserMgrUrlFulture);
  367. strCmdLine.Append(" --hide-controls=true --cache-path=").Append(cachePath);
  368. strCmdLine.Append(" --logExtend=").Append(info).Append(" --top=").Append(std::to_string((LONGLONG)top).c_str());
  369. if (fullscreen)
  370. strCmdLine.Append(" --fullscreen");
  371. DbgEx("ChromiumStart cmdline : %s", strCmdLine);
  372. //control cefclient throught job
  373. auto startRet = startProcessInJob(strCmdLine.GetData(), "");
  374. if (std::get<0>(startRet))
  375. m_cefArr.insert(std::make_pair(info, std::make_tuple(std::get<1>(startRet), std::get<2>(startRet), strCmdLine.GetData())));
  376. else
  377. DbgEx("startProcessInJob failed!");
  378. }
  379. else if (!strcmp(cmdStr, "ChromiumClose"))
  380. {
  381. auto info = cJSON_GetObjectItem(cmdJs.get(), "info")->valuestring;
  382. chromiumCLoseInJob(info);
  383. }
  384. }
  385. #endif
  386. void CChromiumEntity::generateCefclientTimer()
  387. {
  388. m_pTimerListener = new TimerOutHelper<CChromiumEntity>(this, &CChromiumEntity::OnTaskTimerListener, NULL, false);
  389. GetFunction()->SetTimer(CHROMIUM_TIMER_ID, m_pTimerListener, 2000); //间隔执行时间
  390. }
  391. void CChromiumEntity::generateBussinessLimitTimer() {
  392. DbgEx("Start BusinessLimitTimer");
  393. pBusinessLimitTimerListener = new TimerOutHelper<CChromiumEntity>(this, &CChromiumEntity::OnBusinessLimitTimerListener, NULL, false);
  394. GetFunction()->SetTimer(BROWSER_TIMER_ID, pBusinessLimitTimerListener, 5000);
  395. }
  396. void CChromiumEntity::OnTaskTimerListener(void* pData)
  397. {
  398. static int max_restartTime = 3;
  399. DbgEx("OnTaskTimerListener");
  400. if (max_restartTime == 0)
  401. {
  402. DbgEx("max_restartTime == 0, do not restart chromium");
  403. GetFunction()->KillTimer(CHROMIUM_TIMER_ID);
  404. return;
  405. }
  406. //基于Desk2S功能判断,当当前并未启动cefclient时,对cefclient.exe进行清理
  407. if (0 == m_cefArr.size())
  408. DbgEx("kill chromium %s", CModTools::get_mutable_instance().killAllChromium() ? "success" : "fail");
  409. auto rc = CModTools::get_mutable_instance().StartChromiumBrowser();
  410. max_restartTime--;
  411. DbgEx("TaskTimerListen, startChromiumBrowser, rc:%d, pid:%d", rc.first, rc.second);
  412. if (0 == rc.first)
  413. GetFunction()->KillTimer(CHROMIUM_TIMER_ID);
  414. #if (defined _WIN32 || defined _WIN64)
  415. if (rc.first == Error_Succeed && rc.second != 0)
  416. {
  417. HANDLE defaultProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, rc.second);
  418. if (defaultProcess == nullptr)
  419. {
  420. DbgEx("OnTaskTimerListener, openProcess failed");
  421. return;
  422. }
  423. auto ret = assigntoJob(defaultProcess, rc.second);
  424. if (!ret.first)
  425. DbgEx("OnTaskTimerListener, assigntoJob failed");
  426. else
  427. {
  428. auto monitorThread = [&](HANDLE job, HANDLE process) {
  429. while (1)
  430. {
  431. if (WaitForSingleObject(process, 10) != WAIT_OBJECT_0) //process end
  432. DbgEx("default cefclient.exe job:%d, process:%d checkOpen", job, process);
  433. else
  434. {
  435. DbgEx("default cefclient.exe job:%d, process:%d check Closed, try to restart", job, process);
  436. TerminateJobObject(job, 0);
  437. max_restartTime--;
  438. generateCefclientTimer();
  439. //modTools.StartChromiumBrowser();
  440. break;
  441. }
  442. boost::this_thread::sleep_for(boost::chrono::seconds(10));
  443. }
  444. };
  445. if (ret.second != nullptr && defaultProcess != nullptr)
  446. boost::thread(monitorThread, ret.second, defaultProcess).detach();
  447. }
  448. }
  449. if (Error_Succeed != rc.first)
  450. {
  451. DbgEx("OnTaskTimerListener will be called after %d secs, rest restart time %d", 15, max_restartTime);
  452. if (max_restartTime)
  453. GetFunction()->ResetTimer(CHROMIUM_TIMER_ID, 15000);
  454. }
  455. else {
  456. DbgEx("OnTaskTimerListener rc = succeed");
  457. GetFunction()->KillTimer(CHROMIUM_TIMER_ID);
  458. }
  459. #endif
  460. }
  461. SP_BEGIN_ENTITY_MAP()
  462. SP_ENTITY(CChromiumEntity)
  463. SP_END_ENTITY_MAP()
  464. }