Logo ROOT   6.12/07
Reference Guide
THttpWSHandler.cxx
Go to the documentation of this file.
1 // $Id$
2 // Author: Sergey Linev 20/10/2017
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2013, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #include "THttpWSHandler.h"
13 
14 #include "THttpWSEngine.h"
15 #include "THttpCallArg.h"
16 
17 
18 /////////////////////////////////////////////////////////////////////////
19 ///
20 /// THttpWSHandler
21 ///
22 /// Class for user-side handling of websocket with THttpServer
23 /// 1. Create derived from THttpWSHandler class and implement
24 /// ProcessWS() method, where all web sockets request handled.
25 /// 2. Register instance of derived class to running THttpServer
26 ///
27 /// TUserWSHandler *handler = new TUserWSHandler("name1","title");
28 /// THttpServer *server = new THttpServer("http:8090");
29 /// server->Register("/subfolder", handler)
30 ///
31 /// 3. Now server can accept web socket connection from outside.
32 /// For instance, from JavaScirpt one can connect to it with code:
33 ///
34 /// var ws = new WebSocket("ws://hostname:8090/subfolder/name1/root.websocket")
35 ///
36 /// 4. In the ProcessWS(THttpCallArg *arg) method following code should be implemented:
37 ///
38 /// if (arg->IsMethod("WS_CONNECT")) {
39 /// return true; // to accept incoming request
40 /// }
41 ///
42 /// if (arg->IsMethod("WS_READY")) {
43 /// fWSId = arg->GetWSId(); // fWSId should be member of the user class
44 /// return true; // connection established
45 /// }
46 ///
47 /// if (arg->IsMethod("WS_CLOSE")) {
48 /// fWSId = 0;
49 /// return true; // confirm close of socket
50 /// }
51 ///
52 /// if (arg->IsMethod("WS_DATA")) {
53 /// // received data stored as POST data
54 /// std::string str((const char *)arg->GetPostData(), arg->GetPostDataLength());
55 /// std::cout << "got string " << str << std::endl;
56 /// // immediately send data back using websocket id
57 /// SendCharStarWS(fWSId, "our reply");
58 /// return true;
59 /// }
60 ///
61 ///////////////////////////////////////////////////////////////////////////
62 
64 
65 ////////////////////////////////////////////////////////////////////////////////
66 /// normal constructor
67 
68 THttpWSHandler::THttpWSHandler(const char *name, const char *title) :
69  TNamed(name, title), fEngines()
70 {
71 }
72 
74 {
75  TIter iter(&fEngines);
76  THttpWSEngine *engine = 0;
77 
78  while ((engine = (THttpWSEngine *)iter()) != 0)
79  engine->ClearHandle();
80 
81  fEngines.Delete();
82 }
83 
84 
86 {
87  TIter iter(&fEngines);
88  THttpWSEngine *engine = 0;
89 
90  while ((engine = (THttpWSEngine *)iter()) != 0) {
91  if (engine->GetId() == id) return engine;
92  }
93 
94  return 0;
95 }
96 
98 {
99  if (!arg->GetWSId()) return ProcessWS(arg);
100 
101  THttpWSEngine* engine = FindEngine(arg->GetWSId());
102 
103  if (arg->IsMethod("WS_CONNECT")) {
104  // accept all requests, in future one could limit number of connections
105  return ProcessWS(arg);
106  }
107 
108  if (arg->IsMethod("WS_READY")) {
109 
110  if (engine) {
111  Error("HandleWS","WS engine with similar id exists %u\n", arg->GetWSId());
112  fEngines.Remove(engine);
113  delete engine;
114  }
115 
116  THttpWSEngine *wshandle = dynamic_cast<THttpWSEngine *>(arg->TakeWSHandle());
117 
118  fEngines.Add(wshandle);
119 
120  if (!ProcessWS(arg)) {
121  // if connection refused, remove engine again
122  fEngines.Remove(wshandle);
123  delete wshandle;
124  return kFALSE;
125  }
126 
127  return kTRUE;
128  }
129 
130  if (arg->IsMethod("WS_CLOSE")) {
131  // connection is closed, one can remove handle
132 
133  if (engine) {
134  engine->ClearHandle();
135  fEngines.Remove(engine);
136  delete engine;
137  }
138 
139  return ProcessWS(arg);
140  }
141 
142  if (engine && engine->PreviewData(arg)) return kTRUE;
143 
144  return ProcessWS(arg);
145 }
146 
148 {
149  THttpWSEngine* engine = FindEngine(wsid);
150 
151  if (engine) {
152  fEngines.Remove(engine);
153  delete engine;
154  }
155 }
156 
157 void THttpWSHandler::SendWS(UInt_t wsid, const void *buf, int len)
158 {
159  THttpWSEngine* engine = FindEngine(wsid);
160 
161  if (engine) engine->Send(buf, len);
162 }
163 
164 void THttpWSHandler::SendCharStarWS(UInt_t wsid, const char *str)
165 {
166  THttpWSEngine* engine = FindEngine(wsid);
167 
168  if (engine) engine->SendCharStar(str);
169 }
virtual void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition: TList.cxx:467
Bool_t IsMethod(const char *name) const
returns kTRUE if post method is used
Definition: THttpCallArg.h:118
void SendWS(UInt_t wsid, const void *buf, int len)
UInt_t GetWSId() const
get web-socket id
Definition: THttpCallArg.h:97
virtual ~THttpWSHandler()
bool Bool_t
Definition: RtypesCore.h:59
virtual void Send(const void *buf, int len)=0
TList fEngines
! list of of engines in use, cleaned automatically at the end
THttpWSEngine * FindEngine(UInt_t id) const
virtual void SendCharStar(const char *str)
Envelope for sending string via the websocket.
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
virtual Bool_t PreviewData(THttpCallArg *)
Definition: THttpWSEngine.h:35
XFontStruct * id
Definition: TGX11.cxx:108
void CloseWS(UInt_t wsid)
void SendCharStarWS(UInt_t wsid, const char *str)
Bool_t HandleWS(THttpCallArg *arg)
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Definition: TList.cxx:818
virtual UInt_t GetId() const =0
unsigned int UInt_t
Definition: RtypesCore.h:42
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
const Bool_t kFALSE
Definition: RtypesCore.h:88
#define ClassImp(name)
Definition: Rtypes.h:359
virtual Bool_t ProcessWS(THttpCallArg *arg)=0
TNamed * TakeWSHandle()
takeout websocket handle with HTTP call can be done only once
virtual void Add(TObject *obj)
Definition: TList.h:87
virtual void ClearHandle()=0
THttpWSHandler(const char *name, const char *title)
THttpWSHandler.
const Bool_t kTRUE
Definition: RtypesCore.h:87
char name[80]
Definition: TGX11.cxx:109