Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
http: emulate websocket with longpoll instance
Try to produce similar call sequences from THttpServer
There are some other changes required
  • Loading branch information
linev committed Apr 18, 2017
commit dfa31e8ac3a3b23baff5f77e292e5fd5629a955a
66 changes: 66 additions & 0 deletions net/http/src/THttpServer.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "TSystem.h"
#include "TImage.h"
#include "TROOT.h"
#include "TUrl.h"
#include "TClass.h"
#include "TCanvas.h"
#include "TFolder.h"
Expand Down Expand Up @@ -64,6 +65,36 @@ class THttpTimer : public TTimer {
}
};

//////////////////////////////////////////////////////////////////////////////////////////////////


class TLongPollEngine : public THttpWSEngine {
protected:
THttpCallArg *fPoll; ///< polling connection, which can be used for the sending next operation

public:
TLongPollEngine(const char *name, const char *title)
: THttpWSEngine(name, title), fPoll(0)
{
}

virtual ~TLongPollEngine() {}

virtual UInt_t GetId() const { return TString::Hash((void *)this, sizeof(void *)); }

virtual void ClearHandle() { fPoll = 0; }

virtual void Send(const void *buf, int len)
{
}

virtual void SendCharStar(const char *buf)
{
}

};


// =======================================================

//////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -680,6 +711,41 @@ void THttpServer::ProcessRequest(THttpCallArg *arg)
}

return;
} else if (filename == "root.longpoll") {
// ROOT emulation of websocket with polling requests
TCanvas *canv = dynamic_cast<TCanvas *>(fSniffer->FindTObjectInHierarchy(arg->fPathName.Data()));

if (!canv || !canv->GetCanvasImp()) {
// for the moment only TCanvas is used for web sockets
arg->Set404();
} else if (arg->fQuery == "connect") {
// try to emulate websocket connect
// if accepted, reply with connection id, which must be used in the following communications
arg->SetMethod("WS_CONNECT");
if (canv->GetCanvasImp()->ProcessWSRequest(arg) && !arg->Is404()) {
arg->SetMethod("WS_READY");

TLongPollEngine* handle = new TLongPollEngine("longpoll", arg->fPathName.Data());

arg->SetWSId(handle->GetId());
arg->SetWSHandle(handle);

if (canv->GetCanvasImp()->ProcessWSRequest(arg) && !arg->Is404())
arg->SetContent(TString::Format("%u",arg->GetWSId()));
}
} else {
TUrl url;
url.SetOptions(arg->fQuery);
url.ParseOptions();
Int_t connid = url.GetIntValueFromOptions("connection");
arg->SetWSId((UInt_t)connid);
if (url.HasOption("close"))
arg->SetMethod("WS_CLOSE");
else
arg->SetMethod("WS_DATA");
if (!canv->GetCanvasImp()->ProcessWSRequest(arg)) arg->Set404();
}
return;

} else if (fSniffer->Produce(arg->fPathName.Data(), filename.Data(), arg->fQuery.Data(), bindata, bindatalen,
arg->fContent)) {
Expand Down