diff --git a/gui/browserv7/inc/ROOT/RBrowser.hxx b/gui/browserv7/inc/ROOT/RBrowser.hxx index e44a87938ab1c..d2578533a7a60 100644 --- a/gui/browserv7/inc/ROOT/RBrowser.hxx +++ b/gui/browserv7/inc/ROOT/RBrowser.hxx @@ -85,12 +85,12 @@ public: void AddTCanvas() { AddInitWidget("tcanvas"); } void AddRCanvas() { AddInitWidget("rcanvas"); } - /// show Browser in specified place void Show(const RWebDisplayArgs &args = "", bool always_start_new_browser = false); - /// hide Browser void Hide(); + void Sync(); + std::string GetWindowUrl(bool remote); void SetWorkingPath(const std::string &path); diff --git a/gui/browserv7/src/RBrowser.cxx b/gui/browserv7/src/RBrowser.cxx index d93192bc8ca97..e7dcc08ba23d8 100644 --- a/gui/browserv7/src/RBrowser.cxx +++ b/gui/browserv7/src/RBrowser.cxx @@ -303,7 +303,7 @@ RBrowser::RBrowser(bool use_rcanvas) fWebWindow = RWebWindow::Create(); if (!fWebWindow) return; - + fWebWindow->SetDefaultPage("file:rootui5sys/browser/browser.html"); std::string sortby = gEnv->GetValue("WebGui.Browser.SortBy", "name"), @@ -593,6 +593,15 @@ void RBrowser::Hide() fWebWindow->CloseConnections(); } +/////////////////////////////////////////////////////////////////////////////////////////////////////// +/// Run widget Sync method - processing pending actions + +void RBrowser::Sync() +{ + if (fWebWindow) + fWebWindow->Sync(); +} + /////////////////////////////////////////////////////////////////////////////////////////////////////// /// Return URL parameter for the window showing ROOT Browser /// See \ref ROOT::RWebWindow::GetUrl docu for more details diff --git a/gui/browserv7/src/RWebBrowserImp.cxx b/gui/browserv7/src/RWebBrowserImp.cxx index 711b17648f070..e4170f404afc6 100644 --- a/gui/browserv7/src/RWebBrowserImp.cxx +++ b/gui/browserv7/src/RWebBrowserImp.cxx @@ -20,6 +20,14 @@ using namespace ROOT; +class CleanupHandle { + RWebBrowserImp *fImp = nullptr; + public: + + CleanupHandle(RWebBrowserImp *imp) { fImp = imp; } + ~CleanupHandle() { printf("CleanupHandle destroyed\n"); } +}; + //////////////////////////////////////////////////////////////////////////////////////// /// Default constructor @@ -29,6 +37,8 @@ RWebBrowserImp::RWebBrowserImp(TBrowser *b) : TBrowserImp(b) fWebBrowser = std::make_shared(); fWebBrowser->AddTCanvas(); + + fWebBrowser->ClearOnClose(std::make_shared(this)); } //////////////////////////////////////////////////////////////////////////////////////// @@ -42,6 +52,8 @@ RWebBrowserImp::RWebBrowserImp(TBrowser *b, const char *title, UInt_t width, UIn fHeight = height; fWebBrowser = std::make_shared(); fWebBrowser->AddTCanvas(); + + fWebBrowser->ClearOnClose(std::make_shared(this)); } //////////////////////////////////////////////////////////////////////////////////////// @@ -57,6 +69,8 @@ RWebBrowserImp::RWebBrowserImp(TBrowser *b, const char *title, Int_t x, Int_t y, fHeight = height; fWebBrowser = std::make_shared(); fWebBrowser->AddTCanvas(); + + fWebBrowser->ClearOnClose(std::make_shared(this)); } //////////////////////////////////////////////////////////////////////////////////////// diff --git a/gui/webdisplay/inc/ROOT/RWebWindow.hxx b/gui/webdisplay/inc/ROOT/RWebWindow.hxx index 4675f27188316..abbd646068d42 100644 --- a/gui/webdisplay/inc/ROOT/RWebWindow.hxx +++ b/gui/webdisplay/inc/ROOT/RWebWindow.hxx @@ -72,6 +72,7 @@ private: unsigned fConnId{0}; /// fAssgnExec; ///GetLaunchTmout(); + float launch_tmout = fMgr->GetLaunchTmout(), + reconnect_tmout = fMgr->GetReconnectTmout(); ConnectionsList_t selected; + bool do_clear_on_close = false; + { std::lock_guard grd(fConnMutex); auto pred = [&](std::shared_ptr &e) { std::chrono::duration diff = stamp - e->fSendStamp; + float tmout = e->fWasEstablished ? reconnect_tmout : launch_tmout; + if (diff.count() > tmout) { R__LOG_DEBUG(0, WebGUILog()) << "Remove pending connection " << e->fKey << " after " << diff.count() << " sec"; selected.emplace_back(e); @@ -663,7 +668,12 @@ void RWebWindow::CheckPendingConnections() }; fPendingConn.erase(std::remove_if(fPendingConn.begin(), fPendingConn.end(), pred), fPendingConn.end()); + + do_clear_on_close = (selected.size() > 0) && (fPendingConn.size() == 0) && (fConn.size() == 0); } + + if (do_clear_on_close) + fClearOnClose.reset(); } @@ -855,6 +865,7 @@ bool RWebWindow::ProcessWS(THttpCallArg &arg) if (conn) { conn->fWSId = arg.GetWSId(); conn->fActive = true; + conn->fWasEstablished = true; conn->fRecvSeq = 0; conn->fSendSeq = 1; // preserve key for longpoll or when with session key used for HMAC hash of messages @@ -903,13 +914,14 @@ bool RWebWindow::ProcessWS(THttpCallArg &arg) if (conn) { bool do_clear_on_close = false; - if (!conn->fNewKey.empty()) { + if (!conn->fNewKey.empty() && (fMgr->GetReconnectTmout() > 0)) { // case when same handle want to be reused by client with new key std::lock_guard grd(fConnMutex); conn->fKeyUsed = 0; conn->fKey = conn->fNewKey; conn->fNewKey.clear(); conn->fConnId = ++fConnCnt; // change connection id to avoid confusion + conn->fWasEstablished = true; conn->ResetData(); conn->ResetStamps(); // reset stamps, after timeout connection wll be removed fPendingConn.emplace_back(conn); diff --git a/gui/webdisplay/src/RWebWindowsManager.cxx b/gui/webdisplay/src/RWebWindowsManager.cxx index 6ef280036b7c2..f6e628b9635df 100644 --- a/gui/webdisplay/src/RWebWindowsManager.cxx +++ b/gui/webdisplay/src/RWebWindowsManager.cxx @@ -510,6 +510,7 @@ bool RWebWindowsManager::CreateServer(bool with_http) int fcgi_thrds = gEnv->GetValue("WebGui.FastCgiThreads", 10); const char *fcgi_serv = gEnv->GetValue("WebGui.FastCgiServer", ""); fLaunchTmout = gEnv->GetValue("WebGui.LaunchTmout", 30.); + fReconnectTmout = gEnv->GetValue("WebGui.ReconnectTmout", 15.); bool assign_loopback = gWebWinLoopbackMode; const char *http_bind = gEnv->GetValue("WebGui.HttpBind", ""); bool use_secure = RWebWindowWSHandler::GetBoolEnv("WebGui.UseHttps", 0) == 1; @@ -784,6 +785,7 @@ std::string RWebWindowsManager::GetUrl(RWebWindow &win, bool remote, std::string /// WebGui.FirefoxProfilePath: file path to Firefox profile /// WebGui.FirefoxRandomProfile: usage of random Firefox profile "no" - disabled, "yes" - enabled (default) /// WebGui.LaunchTmout: time required to start process in seconds (default 30 s) +/// WebGui.ReconnectTmout: time to reconnect for already existing connection, if negative - no reconnecting possible (default 15 s) /// WebGui.CefTimer: periodic time to run CEF event loop (default 10 ms) /// WebGui.CefUseViews: "yes" - enable / "no" - disable usage of CEF views frameworks (default is platform/version dependent) /// WebGui.OperationTmout: time required to perform WebWindow operation like execute command or update drawings