Isolate WebSocket 0.2-specific code.

* Hide implementation details of the WebSocket server from clients.
* Extract a generic traits class.
This commit is contained in:
Tom Ritchford
2015-01-22 16:48:58 -05:00
parent b357390215
commit 9c3522cb70
14 changed files with 775 additions and 479 deletions

View File

@@ -19,162 +19,21 @@
#include <BeastConfig.h>
#include <ripple/websocket/MakeServer.h>
#include <ripple/websocket/Handler.h>
#include <beast/threads/Thread.h>
#include <beast/cxx14/memory.h> // <memory>
#include <mutex>
#include <ripple/websocket/WebSocket.h>
namespace ripple {
namespace websocket {
//
// This is a light weight, untrusted interface for web clients.
// For now we don't provide proof. Later we will.
//
// Might need to support this header for browsers: Access-Control-Allow-Origin: *
// - https://developer.mozilla.org/en-US/docs/HTTP_access_control
//
//
// Strategy:
// - We only talk to NetworkOPs (so we will work even in thin mode)
// - NetworkOPs is smart enough to subscribe and or pass back messages
//
// VFALCO NOTE NetworkOPs isn't used here...
//
class WSDoorImp
: public WSDoor
, protected beast::Thread
std::unique_ptr<beast::Stoppable> makeServer (ServerDescription const& desc)
{
private:
using LockType = std::recursive_mutex;
using ScopedLockType = std::lock_guard <LockType>;
static std::string const version = "0.2";
WriteLog (lsWARNING, WebSocket) << "Websocket version " << version;
if (version == WebSocket02::versionName())
return makeServer02 (desc);
std::shared_ptr<HTTP::Port> port_;
Resource::Manager& m_resourceManager;
InfoSub::Source& m_source;
LockType m_endpointLock;
std::shared_ptr<websocketpp_02::server_autotls> m_endpoint;
CollectorManager& collectorManager_;
public:
WSDoorImp (HTTP::Port const& port, Resource::Manager& resourceManager,
InfoSub::Source& source, CollectorManager& cm)
: WSDoor (source)
, Thread ("websocket")
, port_(std::make_shared<HTTP::Port>(port))
, m_resourceManager (resourceManager)
, m_source (source)
, collectorManager_ (cm)
{
startThread ();
}
~WSDoorImp ()
{
stopThread ();
}
private:
void run ()
{
WriteLog (lsINFO, WSDoor) <<
"Websocket: '" << port_->name << "' listening on " <<
port_->ip.to_string() << ":" << std::to_string(port_->port) <<
(port_->allow_admin ? "(Admin)" : "");
websocketpp_02::server_autotls::handler::ptr handler (
new WSServerHandler <websocketpp_02::server_autotls> (
port_, m_resourceManager, m_source, collectorManager_));
{
ScopedLockType lock (m_endpointLock);
m_endpoint = std::make_shared<websocketpp_02::server_autotls> (
handler);
}
// Call the main-event-loop of the websocket server.
try
{
m_endpoint->listen (port_->ip, port_->port);
}
catch (websocketpp_02::exception& e)
{
WriteLog (lsWARNING, WSDoor) << "websocketpp_02 exception: "
<< e.what ();
// temporary workaround for websocketpp_02 throwing exceptions on
// access/close races
for (;;)
{
// https://github.com/zaphoyd/websocketpp_02/issues/98
try
{
m_endpoint->get_io_service ().run ();
break;
}
catch (websocketpp_02::exception& e)
{
WriteLog (lsWARNING, WSDoor) << "websocketpp_02 exception: "
<< e.what ();
}
}
}
{
ScopedLockType lock (m_endpointLock);
m_endpoint.reset();
}
stopped ();
}
void onStop ()
{
std::shared_ptr<websocketpp_02::server_autotls> endpoint;
{
ScopedLockType lock (m_endpointLock);
endpoint = m_endpoint;
}
// VFALCO NOTE we probably dont want to block here
// but websocketpp is deficient and broken.
//
if (endpoint)
endpoint->stop ();
signalThreadShouldExit ();
}
};
//------------------------------------------------------------------------------
WSDoor::WSDoor (Stoppable& parent)
: Stoppable ("WSDoor", parent)
{
assert (false);
return {};
}
//------------------------------------------------------------------------------
std::unique_ptr<WSDoor>
make_WSDoor (HTTP::Port const& port, Resource::Manager& resourceManager,
InfoSub::Source& source, CollectorManager& cm)
{
std::unique_ptr<WSDoor> door;
try
{
door = std::make_unique <WSDoorImp> (port, resourceManager, source, cm);
}
catch (...)
{
}
return door;
}
}
} // websocket
} // ripple