File indexing completed on 2026-01-03 10:21:23
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef ROOT7_RWebWindow
0014 #define ROOT7_RWebWindow
0015
0016 #include <ROOT/RWebDisplayHandle.hxx>
0017
0018 #include "ROOT/RConfig.hxx"
0019
0020 #include <memory>
0021 #include <vector>
0022 #include <string>
0023 #include <queue>
0024 #include <map>
0025 #include <functional>
0026 #include <mutex>
0027 #include <thread>
0028 #include <chrono>
0029
0030 class THttpCallArg;
0031 class THttpServer;
0032
0033 namespace ROOT {
0034
0035
0036
0037 using WebWindowConnectCallback_t = std::function<void(unsigned)>;
0038
0039
0040
0041 using WebWindowDataCallback_t = std::function<void(unsigned, const std::string &)>;
0042
0043
0044
0045
0046
0047
0048 using WebWindowWaitFunc_t = std::function<int(double)>;
0049
0050 class RFileDialog;
0051 class RWebWindowsManager;
0052 class RWebWindowWSHandler;
0053
0054 class RWebWindow {
0055
0056 friend class RWebWindowsManager;
0057 friend class RWebWindowWSHandler;
0058 friend class RWebDisplayHandle;
0059 friend class RFileDialog;
0060
0061 private:
0062 using timestamp_t = std::chrono::time_point<std::chrono::system_clock>;
0063
0064 struct QueueItem {
0065 int fChID{1};
0066 bool fText{true};
0067 std::string fData;
0068 QueueItem(int chid, bool txt, std::string &&data) : fChID(chid), fText(txt), fData(data) {}
0069 };
0070
0071 struct WebConn {
0072 unsigned fConnId{0};
0073 bool fHeadlessMode{false};
0074 bool fWasFirst{false};
0075 bool fWasEstablished{false};
0076 std::string fKey;
0077 int fKeyUsed{0};
0078 std::string fNewKey;
0079 std::unique_ptr<RWebDisplayHandle> fDisplayHandle;
0080 std::shared_ptr<THttpCallArg> fHold;
0081 timestamp_t fSendStamp;
0082 bool fActive{false};
0083 unsigned fWSId{0};
0084 int fReady{0};
0085 mutable std::mutex fMutex;
0086 timestamp_t fRecvStamp;
0087 int fRecvCount{0};
0088 int fSendCredits{0};
0089 int fClientCredits{0};
0090 bool fDoingSend{false};
0091 unsigned long fRecvSeq{0};
0092 unsigned long fSendSeq{1};
0093 std::queue<QueueItem> fQueue;
0094 std::map<int,std::shared_ptr<RWebWindow>> fEmbed;
0095 WebConn() = default;
0096 WebConn(unsigned connid) : fConnId(connid) {}
0097 WebConn(unsigned connid, unsigned wsid) : fConnId(connid), fActive(true), fWSId(wsid) {}
0098 WebConn(unsigned connid, bool headless_mode, const std::string &key)
0099 : fConnId(connid), fHeadlessMode(headless_mode), fKey(key)
0100 {
0101 ResetStamps();
0102 }
0103 ~WebConn();
0104
0105 void ResetStamps() { fSendStamp = fRecvStamp = std::chrono::system_clock::now(); }
0106
0107 void ResetData()
0108 {
0109 fActive = false;
0110 fWSId = 0;
0111 fReady = 0;
0112 fDoingSend = false;
0113 fSendCredits = 0;
0114 fClientCredits = 0;
0115 fRecvSeq = 0;
0116 fSendSeq = 1;
0117 while (!fQueue.empty())
0118 fQueue.pop();
0119 }
0120 };
0121
0122 struct MasterConn {
0123 unsigned connid{0};
0124 int channel{-1};
0125 MasterConn(unsigned _connid, int _channel) : connid(_connid), channel(_channel) {}
0126 };
0127
0128 enum EQueueEntryKind { kind_None, kind_Connect, kind_Data, kind_Disconnect };
0129
0130 struct QueueEntry {
0131 unsigned fConnId{0};
0132 EQueueEntryKind fKind{kind_None};
0133 std::string fData;
0134 QueueEntry() = default;
0135 QueueEntry(unsigned connid, EQueueEntryKind kind, std::string &&data) : fConnId(connid), fKind(kind), fData(data) {}
0136 };
0137
0138 using ConnectionsList_t = std::vector<std::shared_ptr<WebConn>>;
0139
0140 std::shared_ptr<RWebWindowsManager> fMgr;
0141 std::shared_ptr<RWebWindow> fMaster;
0142 std::vector<MasterConn> fMasterConns;
0143 std::string fDefaultPage;
0144 std::string fPanelName;
0145 unsigned fId{0};
0146 bool fUseServerThreads{false};
0147 bool fUseProcessEvents{false};
0148 bool fProcessMT{false};
0149 bool fSendMT{false};
0150 bool fRequireAuthKey{true};
0151 std::shared_ptr<RWebWindowWSHandler> fWSHandler;
0152 unsigned fConnCnt{0};
0153 ConnectionsList_t fPendingConn;
0154 ConnectionsList_t fConn;
0155 mutable std::mutex fConnMutex;
0156 unsigned fConnLimit{1};
0157 std::string fConnToken;
0158 bool fNativeOnlyConn{false};
0159 bool fUseCurrentDir{false};
0160 unsigned fMaxQueueLength{10};
0161 WebWindowConnectCallback_t fConnCallback;
0162 WebWindowDataCallback_t fDataCallback;
0163 WebWindowConnectCallback_t fDisconnCallback;
0164 std::thread::id fCallbacksThrdId;
0165 bool fCallbacksThrdIdSet{false};
0166 bool fHasWindowThrd{false};
0167 std::thread fWindowThrd;
0168 std::queue<QueueEntry> fInputQueue;
0169 std::mutex fInputQueueMutex;
0170 unsigned fWidth{0}, fHeight{0};
0171 int fX{-1}, fY{-1};
0172 float fOperationTmout{50.};
0173 std::string fClientVersion;
0174 std::string fProtocolFileName;
0175 int fProtocolCnt{-1};
0176 unsigned fProtocolConnId{0};
0177 std::string fProtocolPrefix;
0178 std::string fProtocol;
0179 std::string fUserArgs;
0180 std::shared_ptr<void> fClearOnClose;
0181 static std::string gJSROOTsettings;
0182
0183 std::shared_ptr<RWebWindowWSHandler> CreateWSHandler(std::shared_ptr<RWebWindowsManager> mgr, unsigned id, double tmout);
0184
0185 bool ProcessWS(THttpCallArg &arg);
0186
0187 void CompleteWSSend(unsigned wsid);
0188
0189 ConnectionsList_t GetWindowConnections(unsigned connid = 0, bool only_active = false) const;
0190
0191
0192 std::shared_ptr<WebConn> FindConnection(unsigned wsid);
0193
0194 void ClearConnection(std::shared_ptr<WebConn> &conn, bool provide_signal = false);
0195
0196 std::shared_ptr<WebConn> RemoveConnection(unsigned wsid, bool provide_signal = false);
0197
0198 bool _CanTrustIn(std::shared_ptr<WebConn> &conn, const std::string &key, const std::string &ntry, bool remote, bool test_first_time);
0199
0200 std::string _MakeSendHeader(std::shared_ptr<WebConn> &conn, bool txt, const std::string &data, int chid);
0201
0202 void ProvideQueueEntry(unsigned connid, EQueueEntryKind kind, std::string &&arg);
0203
0204 void InvokeCallbacks(bool force = false);
0205
0206 void SubmitData(unsigned connid, bool txt, std::string &&data, int chid = 1);
0207
0208 bool CheckDataToSend(std::shared_ptr<WebConn> &conn);
0209
0210 void CheckDataToSend(bool only_once = false);
0211
0212 bool HasKey(const std::string &key, bool also_newkey = false) const;
0213
0214 void RemoveKey(const std::string &key);
0215
0216 std::string GenerateKey() const;
0217
0218 void CheckPendingConnections();
0219
0220 void CheckInactiveConnections();
0221
0222 unsigned AddDisplayHandle(bool headless_mode, const std::string &key, std::unique_ptr<RWebDisplayHandle> &handle);
0223
0224 unsigned AddEmbedWindow(std::shared_ptr<RWebWindow> window, unsigned connid, int channel);
0225
0226 void RemoveEmbedWindow(unsigned connid, int channel);
0227
0228 void AddMasterConnection(std::shared_ptr<RWebWindow> window, unsigned connid, int channel);
0229
0230 std::vector<MasterConn> GetMasterConnections(unsigned connid = 0) const;
0231
0232 void RemoveMasterConnection(unsigned connid = 0);
0233
0234 bool ProcessBatchHolder(std::shared_ptr<THttpCallArg> &arg);
0235
0236 std::string GetConnToken() const;
0237
0238 unsigned MakeHeadless(bool create_new = false);
0239
0240 unsigned FindHeadlessConnection();
0241
0242 static std::function<bool(const std::shared_ptr<RWebWindow> &, unsigned, const std::string &)> gStartDialogFunc;
0243
0244 static void SetStartDialogFunc(std::function<bool(const std::shared_ptr<RWebWindow> &, unsigned, const std::string &)>);
0245
0246 static std::string HMAC(const std::string &key, const std::string &sessionKey, const char *msg, int msglen);
0247
0248 public:
0249
0250 RWebWindow();
0251
0252 ~RWebWindow();
0253
0254
0255 unsigned GetId() const { return fId; }
0256
0257
0258 std::shared_ptr<RWebWindowsManager> GetManager() const { return fMgr; }
0259
0260
0261
0262
0263
0264 void SetDefaultPage(const std::string &page) { fDefaultPage = page; }
0265
0266 void SetPanelName(const std::string &name);
0267
0268
0269 void SetGeometry(unsigned width, unsigned height)
0270 {
0271 fWidth = width;
0272 fHeight = height;
0273 }
0274
0275
0276 void SetPosition(unsigned x, unsigned y)
0277 {
0278 fX = x;
0279 fY = y;
0280 }
0281
0282
0283
0284
0285 unsigned GetWidth() const { return fWidth; }
0286
0287
0288
0289 unsigned GetHeight() const { return fHeight; }
0290
0291
0292
0293 int GetX() const { return fX; }
0294
0295
0296
0297 int GetY() const { return fY; }
0298
0299 void SetConnLimit(unsigned lmt = 0);
0300
0301 unsigned GetConnLimit() const;
0302
0303 void SetConnToken(const std::string &token = "");
0304
0305
0306
0307 void SetMaxQueueLength(unsigned len = 10) { fMaxQueueLength = len; }
0308
0309
0310
0311 unsigned GetMaxQueueLength() const { return fMaxQueueLength; }
0312
0313
0314
0315 void SetNativeOnlyConn(bool on = true) { fNativeOnlyConn = on; }
0316
0317
0318
0319 bool IsNativeOnlyConn() const { return fNativeOnlyConn; }
0320
0321
0322
0323 void SetRequireAuthKey(bool on) { fRequireAuthKey = on; }
0324
0325
0326
0327 bool IsRequireAuthKey() const { return fRequireAuthKey; }
0328
0329
0330
0331 void SetUseCurrentDir(bool on = true) { fUseCurrentDir = on; }
0332
0333
0334
0335 bool IsUseCurrentDir() const { return fUseCurrentDir; }
0336
0337 void SetClientVersion(const std::string &vers);
0338
0339 std::string GetClientVersion() const;
0340
0341 void SetUserArgs(const std::string &args);
0342
0343 std::string GetUserArgs() const;
0344
0345 int NumConnections(bool with_pending = false) const;
0346
0347 unsigned GetConnectionId(int num = 0) const;
0348
0349 std::vector<unsigned> GetConnections(unsigned excludeid = 0) const;
0350
0351 bool HasConnection(unsigned connid = 0, bool only_active = true) const;
0352
0353 void CloseConnections();
0354
0355 void CloseConnection(unsigned connid);
0356
0357
0358 float GetOperationTmout() const { return fOperationTmout; }
0359
0360
0361 void SetOperationTmout(float tm = 50.) { fOperationTmout = tm; }
0362
0363 std::string GetUrl(bool remote = true);
0364
0365 THttpServer *GetServer();
0366
0367 void Sync();
0368
0369 void Run(double tm = 0.);
0370
0371 unsigned Show(const RWebDisplayArgs &args = "");
0372
0373 unsigned GetDisplayConnection() const;
0374
0375
0376 bool IsShown() const { return GetDisplayConnection() != 0; }
0377
0378 bool CanSend(unsigned connid, bool direct = true) const;
0379
0380 int GetSendQueueLength(unsigned connid) const;
0381
0382 void Send(unsigned connid, const std::string &data);
0383
0384 void SendBinary(unsigned connid, const void *data, std::size_t len);
0385
0386 void SendBinary(unsigned connid, std::string &&data);
0387
0388 void RecordData(const std::string &fname = "protocol.json", const std::string &fprefix = "");
0389
0390 std::string GetAddr() const;
0391
0392 _R__DEPRECATED_LATER("Use GetUrl() to get valid connection URL") std::string GetRelativeAddr(const std::shared_ptr<RWebWindow> &win) const;
0393
0394 _R__DEPRECATED_LATER("Use GetAddr() to get valid connection URL") std::string GetRelativeAddr(const RWebWindow &win) const;
0395
0396 void SetCallBacks(WebWindowConnectCallback_t conn, WebWindowDataCallback_t data, WebWindowConnectCallback_t disconn = nullptr);
0397
0398 void Reset();
0399
0400 void SetConnectCallBack(WebWindowConnectCallback_t func);
0401
0402 void SetDataCallBack(WebWindowDataCallback_t func);
0403
0404 void SetDisconnectCallBack(WebWindowConnectCallback_t func);
0405
0406 void SetClearOnClose(const std::shared_ptr<void> &handle = nullptr);
0407
0408 void AssignThreadId();
0409
0410 void UseServerThreads();
0411
0412 int WaitFor(WebWindowWaitFunc_t check);
0413
0414 int WaitForTimed(WebWindowWaitFunc_t check);
0415
0416 int WaitForTimed(WebWindowWaitFunc_t check, double duration);
0417
0418 void StartThread();
0419
0420 void StopThread();
0421
0422 void TerminateROOT();
0423
0424 static std::shared_ptr<RWebWindow> Create();
0425
0426 static unsigned ShowWindow(std::shared_ptr<RWebWindow> window, const RWebDisplayArgs &args = "");
0427
0428 static bool IsFileDialogMessage(const std::string &msg);
0429
0430 static bool EmbedFileDialog(const std::shared_ptr<RWebWindow> &window, unsigned connid, const std::string &args);
0431
0432 static void SetJSROOTSettings(const std::string &json);
0433 };
0434
0435 }
0436
0437 #endif