45int RWebWindowWSHandler::GetBoolEnv(
const std::string &
name,
int dflt)
47 const char *undef =
"<undefined>";
49 if (!
value)
return dflt;
50 std::string svalue =
value;
51 if (svalue == undef)
return dflt;
53 if (svalue ==
"yes")
return 1;
54 if (svalue ==
"no")
return 0;
78 static std::shared_ptr<RWebWindowsManager> sInstance = std::make_shared<RWebWindowsManager>();
127 fAssgnExec = std::make_unique<TExec>(
"init_threadid",
"ROOT::Experimental::RWebWindowsManager::AssignMainThrd();");
151 win.fUseServerThreads =
false;
152 win.fProcessMT =
false;
153 win.fCallbacksThrdIdSet =
true;
171 if (!fname || !*fname)
176 R__LOG_ERROR(
WebGUILog()) <<
"Problem with open listener socket " << fname <<
", check ROOT_LISTENER_SOCKET environment variable";
180 int res =
s.SendRaw(msg.c_str(), msg.length());
288 if (
gROOT->GetWebDisplay() ==
"off")
292 std::lock_guard<std::recursive_mutex> grd(
fMutex);
296 fServer = std::make_unique<THttpServer>(
"basic_sniffer");
307 if (send_thrds != -1)
328 R__LOG_ERROR(
WebGUILog()) <<
"Path to ROOT ui5 sources " << ui5dir <<
" not found, set ROOTUI5SYS correctly";
332 fServer->AddLocation(
"rootui5sys/", ui5dir.
Data());
335 if (!with_http ||
fServer->IsAnyEngine())
339 int http_min =
gEnv->
GetValue(
"WebGui.HttpPortMin", 8800);
340 int http_max =
gEnv->
GetValue(
"WebGui.HttpPortMax", 9800);
341 int http_timer =
gEnv->
GetValue(
"WebGui.HttpTimer", 10);
342 int http_thrds =
gEnv->
GetValue(
"WebGui.HttpThreads", 10);
343 int http_wstmout =
gEnv->
GetValue(
"WebGui.HttpWSTmout", 10000);
344 int http_maxage =
gEnv->
GetValue(
"WebGui.HttpMaxAge", -1);
345 const char *extra_args =
gEnv->
GetValue(
"WebGui.HttpExtraArgs",
"");
346 int fcgi_port =
gEnv->
GetValue(
"WebGui.FastCgiPort", 0);
347 int fcgi_thrds =
gEnv->
GetValue(
"WebGui.FastCgiThreads", 10);
348 const char *fcgi_serv =
gEnv->
GetValue(
"WebGui.FastCgiServer",
"");
351 const char *http_bind =
gEnv->
GetValue(
"WebGui.HttpBind",
"");
353 const char *ssl_cert =
gEnv->
GetValue(
"WebGui.ServerCert",
"rootserver.pem");
355 const char *unix_socket =
gSystem->
Getenv(
"ROOT_WEBGUI_SOCKET");
356 if (!unix_socket || !*unix_socket)
358 const char *unix_socket_mode =
gEnv->
GetValue(
"WebGui.UnixSocketMode",
"0700");
359 bool use_unix_socket = unix_socket && *unix_socket;
362 fcgi_port = http_port = -1;
366 if ((http_port < 0) && (fcgi_port <= 0) && !use_unix_socket) {
381 if (http_max - http_min < ntry)
382 ntry = http_max - http_min;
391 while (ntry-- >= 0) {
392 if ((http_port == 0) && (fcgi_port <= 0) && !use_unix_socket) {
393 if ((http_min <= 0) || (http_max <= http_min)) {
394 R__LOG_ERROR(
WebGUILog()) <<
"Wrong HTTP range configuration, check WebGui.HttpPortMin/Max variables";
398 http_port = (
int)(http_min + (http_max - http_min) *
gRandom->
Rndm(1));
403 engine.
Form(
"fastcgi:%d?thrds=%d", fcgi_port, fcgi_thrds);
404 if (!
fServer->CreateEngine(engine))
406 if (fcgi_serv && (strlen(fcgi_serv) > 0))
412 if (use_unix_socket) {
413 engine.
Form(
"socket:%s?socket_mode=%s&", unix_socket, unix_socket_mode);
415 url = use_secure ?
"https://" :
"http://";
416 engine.
Form(
"%s:%d?", (use_secure ?
"https" :
"http"), http_port);
417 if (assign_loopback) {
418 engine.
Append(
"loopback&");
420 }
else if (http_bind && (strlen(http_bind) > 0)) {
430 if (http_maxage >= 0)
434 engine.
Append(
"&ssl_cert=");
438 if (extra_args && strlen(extra_args) > 0) {
440 engine.
Append(extra_args);
443 if (
fServer->CreateEngine(engine)) {
444 if (use_unix_socket) {
446 fAddr.append(unix_socket);
448 }
else if (http_port > 0) {
451 fAddr.append(std::to_string(http_port));
456 use_unix_socket =
false;
471 std::lock_guard<std::recursive_mutex> grd(
fMutex);
478 std::shared_ptr<RWebWindow>
win = std::make_shared<RWebWindow>();
485 double dflt_tmout =
gEnv->
GetValue(
"WebGui.OperationTmout", 50.);
490 std::string fname, prefix;
492 prefix = std::string(
"f") + std::to_string(
fIdCnt) +
"_";
493 fname = std::string(
"protcol") + std::to_string(
fIdCnt) +
".json";
495 fname =
"protocol.json";
497 win->RecordData(fname, prefix);
504 win->UseServerThreads();
506 win->UseServerThreads();
508 const char *token =
gEnv->
GetValue(
"WebGui.ConnToken",
"");
510 win->SetConnToken(token);
512 fServer->RegisterWS(wshandler);
537 std::string addr =
"/";
539 addr.append(
win.fWSHandler->GetName());
612 auto token =
win.GetConnToken();
615 std::lock_guard<std::recursive_mutex> grd(
fMutex);
622 std::string key =
win.GenerateKey();
641 if (!normal_http && (
gEnv->
GetValue(
"WebGui.ForceHttp", 0) == 1))
644 std::string url =
GetUrl(
win, normal_http);
649 if (normal_http &&
fAddr.empty()) {
663 auto winurl = args.
GetUrl();
664 winurl.erase(0,
fAddr.length());
669 std::cout <<
"New web window: " << args.
GetUrl() << std::endl;
673 if (
fAddr.compare(0,9,
"socket://") == 0)
676#if !defined(R__MACOSX) && !defined(R__WIN32)
678 const char *varname =
"WebGui.CheckRemoteDisplay";
681 if (displ && *displ && (*displ !=
':')) {
684 "ROOT web-based widget started in the session where DISPLAY set to " << displ <<
"\n" <<
685 "Means web browser will be displayed on remote X11 server which is usually very inefficient\n"
686 "One can start ROOT session in server mode like \"root -b --web=server:8877\" and forward http port to display node\n"
687 "Or one can use rootssh script to configure pore forwarding and display web widgets automatically\n"
688 "Find more info on https://root.cern/for_developers/root7/#rbrowser\n"
689 "This message can be disabled by setting \"" << varname <<
": no\" in .rootrc file\n";
720 int res = 0,
cnt = 0;
723 auto start = std::chrono::high_resolution_clock::now();
729 while ((res = check(spent)) == 0) {
738 std::this_thread::sleep_for(std::chrono::milliseconds(
cnt > 5000 ? 10 : 1));
740 std::chrono::duration<double, std::milli> elapsed = std::chrono::high_resolution_clock::now() - start;
742 spent = elapsed.count() * 1
e-3;
744 if (timed && (spent > timelimit))
#define R__LOG_WARNING(...)
#define R__LOG_ERROR(...)
static bool gWebWinMainThrdSet
static std::thread::id gWebWinMainThrd
This thread id used to identify main application thread, where ROOT event processing runs To inject c...
R__EXTERN TApplication * gApplication
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize id
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t win
R__EXTERN TRandom * gRandom
R__EXTERN TSystem * gSystem
Holds different arguments for starting browser with RWebDisplayHandle::Display() method.
std::string GetBrowserName() const
Returns configured browser name.
bool IsSupportHeadless() const
returns true if browser supports headless mode
bool IsHeadless() const
returns headless mode
RWebDisplayArgs & SetUrl(const std::string &url)
set window url
bool IsInteractiveBrowser() const
returns true if interactive browser window supposed to be started
int GetHeight() const
returns preferable web window height
void SetHttpServer(THttpServer *serv)
set http server instance, used for window display
EBrowserKind GetBrowserKind() const
returns configured browser kind, see EBrowserKind for supported values
void AppendUrlOpt(const std::string &opt)
append extra url options, add "&" as separator if required
bool IsLocalDisplay() const
returns true if local display like CEF or Qt5 QWebEngine should be used
@ kEmbedded
window will be embedded into other, no extra browser need to be started
@ kServer
indicates that ROOT runs as server and just printouts window URL, browser should be started by the us...
@ kOff
disable web display, do not start any browser
RWebDisplayArgs & SetHeight(int h=0)
set preferable web window height
const std::string & GetUrl() const
returns window url
int GetWidth() const
returns preferable web window width
RWebDisplayArgs & SetWidth(int w=0)
set preferable web window width
static std::unique_ptr< RWebDisplayHandle > Display(const RWebDisplayArgs &args)
Create web display.
static int GetBoolEnv(const std::string &name, int dfl=-1)
Parse boolean gEnv variable which should be "yes" or "no".
Represents web window, which can be shown in web browser or any other supported environment.
void AssignWindowThreadId(RWebWindow &win)
Assign thread id for window Required in case of external process events.
std::unique_ptr< THttpServer > fServer
! central communication with the all used displays
std::string GetUrl(const RWebWindow &win, bool remote=false)
Provide URL address to access specified window from inside or from remote.
bool CreateServer(bool with_http=false)
Creates http server, if required - with real http engine (civetweb) One could configure concrete HTTP...
RWebWindowsManager()
window manager constructor Required here for correct usage of unique_ptr<THttpServer>
int WaitFor(RWebWindow &win, WebWindowWaitFunc_t check, bool timed=false, double tm=-1)
Waits until provided check function or lambdas returns non-zero value Regularly calls WebWindow::Sync...
std::recursive_mutex fMutex
! main mutex, used for window creations
unsigned fIdCnt
! counter for identifiers
unsigned ShowWindow(RWebWindow &win, const RWebDisplayArgs &args)
Show window in specified location, see Show() method for more details.
std::string fAddr
! HTTP address of the server
bool fUseSenderThreads
! use extra threads for sending data from RWebWindow to clients
void Terminate()
Terminate http server and ROOT application.
~RWebWindowsManager()
window manager destructor Required here for correct usage of unique_ptr<THttpServer>
THttpServer * GetServer() const
Returns THttpServer instance.
WebWindowShowCallback_t fShowCallback
! function called for each RWebWindow::Show call
static void AssignMainThrd()
Re-assigns main thread id Normally main thread id recognized at the moment when library is loaded It ...
std::unique_ptr< TExec > fAssgnExec
! special exec to assign thread id via ProcessEvents
bool IsUseHttpThread() const
Returns true if http server use special thread for requests processing (default off)
static bool IsMainThrd()
Returns true when called from main process Main process recognized at the moment when library is load...
static std::shared_ptr< RWebWindowsManager > & Instance()
Returns default window manager Used to display all standard ROOT elements like TCanvas or TFitPanel.
bool fUseHttpThrd
! use special thread for THttpServer
bool InformListener(const std::string &msg)
If ROOT_LISTENER_SOCKET variable is configured, message will be sent to that unix socket.
void Unregister(RWebWindow &win)
Release all references to specified window Called from RWebWindow destructor.
float fLaunchTmout
! timeout in seconds to start browser process, default 30s
bool fExternalProcessEvents
! indicate that there are external process events engine
std::shared_ptr< RWebWindow > CreateWindow()
Creates new window To show window, RWebWindow::Show() have to be called.
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
virtual void SetValue(const char *name, const char *value, EEnvLevel level=kEnvChange, const char *type=nullptr)
Set the value of a resource or create a new resource.
Bool_t Connect(const char *signal, const char *receiver_class, void *receiver, const char *slot)
Non-static method is used to connect from the signal of this object to the receiver slot.
Bool_t Disconnect(const char *signal=nullptr, void *receiver=nullptr, const char *slot=nullptr)
Disconnects signal of this object from slot of receiver.
static const TString & GetDataDir()
Get the data directory in the installation. Static utility function.
virtual void SetSeed(ULong_t seed=0)
Set the random generator seed.
Double_t Rndm() override
Machine independent random number generator.
const char * Data() const
TString & Append(const char *cs)
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
virtual const char * Getenv(const char *env)
Get environment variable.
virtual void Sleep(UInt_t milliSec)
Sleep milliSec milli seconds.
virtual Bool_t ProcessEvents()
Process pending events (GUI, timers, sockets).
static void SingleShot(Int_t milliSec, const char *receiver_class, void *receiver, const char *method)
This static function calls a slot after a given time interval.
RLogChannel & WebGUILog()
Log channel for WebGUI diagnostics.
std::function< int(double)> WebWindowWaitFunc_t
function signature for waiting call-backs Such callback used when calling thread need to waits for so...
void(off) SmallVectorTemplateBase< T
static constexpr double s