mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Add WebSocket 04 interface.
* New WebSocket04 traits class implements strategies. * New "websocket_version" configuration setting selects between 0.2 and 0.4.
This commit is contained in:
@@ -810,7 +810,7 @@ public:
|
||||
if (! port.websockets())
|
||||
continue;
|
||||
auto server = websocket::makeServer (
|
||||
{port, *m_resourceManager, getOPs(), m_journal,
|
||||
{port, *m_resourceManager, getOPs(), m_journal, getConfig(),
|
||||
*m_collectorManager});
|
||||
if (!server)
|
||||
{
|
||||
|
||||
29
src/ripple/unity/websocket04.cpp
Normal file
29
src/ripple/unity/websocket04.cpp
Normal file
@@ -0,0 +1,29 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <BeastConfig.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# ifndef _WEBSOCKETPP_CONSTEXPR_TOKEN_
|
||||
# define _WEBSOCKETPP_CONSTEXPR_TOKEN_
|
||||
# endif
|
||||
#endif
|
||||
#define _WEBSOCKETPP_CPP11_STL_
|
||||
|
||||
#include <ripple/websocket/WebSocket04.cpp>
|
||||
74
src/ripple/websocket/Config04.h
Normal file
74
src/ripple/websocket/Config04.h
Normal file
@@ -0,0 +1,74 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLED_RIPPLE_WEBSOCKET_CONFIG04_H
|
||||
#define RIPPLED_RIPPLE_WEBSOCKET_CONFIG04_H
|
||||
|
||||
|
||||
#include <ripple/websocket/AutoSocket.h>
|
||||
#include <ripple/websocket/Logger.h>
|
||||
|
||||
#include <websocketpp/config/core.hpp>
|
||||
#include <websocketpp/server.hpp>
|
||||
#include <websocketpp/transport/asio/endpoint.hpp>
|
||||
|
||||
namespace ripple {
|
||||
namespace websocket {
|
||||
|
||||
/** This is a config traits class, copied from
|
||||
websocketpp/websocketpp/config/asio_no_tls.hpp*/
|
||||
|
||||
using ConfigBase04 = websocketpp::config::core;
|
||||
|
||||
struct Config04 : ConfigBase04 {
|
||||
typedef ConfigBase04 base;
|
||||
typedef Config04 type;
|
||||
typedef base::concurrency_type concurrency_type;
|
||||
|
||||
typedef base::request_type request_type;
|
||||
typedef base::response_type response_type;
|
||||
|
||||
typedef base::message_type message_type;
|
||||
typedef base::con_msg_manager_type con_msg_manager_type;
|
||||
typedef base::endpoint_msg_manager_type endpoint_msg_manager_type;
|
||||
|
||||
typedef Logger <LoggerType::access> alog_type;
|
||||
typedef Logger <LoggerType::error> elog_type;
|
||||
|
||||
typedef base::rng_type rng_type;
|
||||
|
||||
struct transport_config : public base::transport_config {
|
||||
typedef type::concurrency_type concurrency_type;
|
||||
typedef type::alog_type alog_type;
|
||||
typedef type::elog_type elog_type;
|
||||
typedef type::request_type request_type;
|
||||
typedef type::response_type response_type;
|
||||
// typedef AutoSocket<con_type, std::error_code>
|
||||
typedef websocketpp::transport::asio::basic_socket::endpoint
|
||||
socket_type;
|
||||
};
|
||||
|
||||
typedef websocketpp::transport::asio::endpoint<transport_config>
|
||||
transport_type;
|
||||
};
|
||||
|
||||
} // websocket
|
||||
} // ripple
|
||||
|
||||
#endif
|
||||
@@ -18,6 +18,7 @@
|
||||
//==============================================================================
|
||||
|
||||
#include <BeastConfig.h>
|
||||
#include <ripple/basics/BasicConfig.h>
|
||||
#include <ripple/websocket/MakeServer.h>
|
||||
#include <ripple/websocket/WebSocket.h>
|
||||
|
||||
@@ -26,13 +27,16 @@ namespace websocket {
|
||||
|
||||
std::unique_ptr<beast::Stoppable> makeServer (ServerDescription const& desc)
|
||||
{
|
||||
static std::string const version = "0.2";
|
||||
auto version = get<std::string> (
|
||||
desc.config["server"], "websocket_version");
|
||||
if (version.empty())
|
||||
version = WebSocket02::versionName();
|
||||
|
||||
WriteLog (lsWARNING, WebSocket) << "Websocket version " << version;
|
||||
if (version == WebSocket02::versionName())
|
||||
return makeServer02 (desc);
|
||||
|
||||
assert (false);
|
||||
return {};
|
||||
assert (version == "04");
|
||||
return makeServer04 (desc);
|
||||
}
|
||||
|
||||
} // websocket
|
||||
|
||||
@@ -28,6 +28,8 @@ namespace beast { class Stoppable; }
|
||||
|
||||
namespace ripple {
|
||||
|
||||
class BasicConfig;
|
||||
|
||||
namespace Resource { class Manager; }
|
||||
|
||||
namespace websocket {
|
||||
@@ -38,6 +40,7 @@ struct ServerDescription
|
||||
Resource::Manager& resourceManager;
|
||||
InfoSub::Source& source;
|
||||
beast::Journal& journal;
|
||||
BasicConfig const& config;
|
||||
CollectorManager& collectorManager;
|
||||
};
|
||||
|
||||
|
||||
@@ -35,8 +35,8 @@ class Server
|
||||
{
|
||||
private:
|
||||
// TODO: why is this recursive?
|
||||
using LockType = typename std::recursive_mutex;
|
||||
using ScopedLockType = typename std::lock_guard <LockType>;
|
||||
using LockType = std::recursive_mutex;
|
||||
using ScopedLockType = std::lock_guard <LockType>;
|
||||
|
||||
ServerDescription desc_;
|
||||
LockType m_endpointLock;
|
||||
|
||||
152
src/ripple/websocket/WebSocket04.cpp
Normal file
152
src/ripple/websocket/WebSocket04.cpp
Normal file
@@ -0,0 +1,152 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/websocket/WebSocket04.h>
|
||||
#include <ripple/websocket/Handler.h>
|
||||
#include <ripple/websocket/Server.h>
|
||||
|
||||
#include <boost/make_shared.hpp>
|
||||
|
||||
namespace ripple {
|
||||
namespace websocket {
|
||||
|
||||
char const* WebSocket04::versionName()
|
||||
{
|
||||
return "websocketpp 0.40";
|
||||
}
|
||||
|
||||
void WebSocket04::handleDisconnect (Connection& connection)
|
||||
{
|
||||
connection.close (websocketpp::close::status::protocol_error,
|
||||
"overload");
|
||||
}
|
||||
|
||||
void WebSocket04::closeTooSlowClient (
|
||||
Connection& connection,
|
||||
unsigned int timeout,
|
||||
std::string const& message)
|
||||
{
|
||||
connection.close (
|
||||
websocketpp::close::status::value (timeout), message);
|
||||
}
|
||||
|
||||
bool WebSocket04::isTextMessage (Message const& message)
|
||||
{
|
||||
return message.get_opcode () == websocketpp::frame::opcode::text;
|
||||
}
|
||||
|
||||
using HandlerPtr04 = WebSocket04::HandlerPtr;
|
||||
using EndpointPtr04 = WebSocket04::EndpointPtr;
|
||||
|
||||
HandlerPtr04 WebSocket04::makeHandler (ServerDescription const& desc)
|
||||
{
|
||||
return std::make_shared <HandlerImpl <WebSocket04>> (desc);
|
||||
}
|
||||
|
||||
EndpointPtr04 WebSocket04::makeEndpoint (HandlerPtr&& handler)
|
||||
{
|
||||
auto endpoint = std::make_shared <Endpoint> (std::move (handler));
|
||||
|
||||
endpoint->set_open_handler (
|
||||
[endpoint] (websocketpp::connection_hdl hdl) {
|
||||
if (auto conn = endpoint->get_con_from_hdl(hdl))
|
||||
endpoint->handler()->on_open (conn);
|
||||
});
|
||||
|
||||
endpoint->set_close_handler (
|
||||
[endpoint] (websocketpp::connection_hdl hdl) {
|
||||
if (auto conn = endpoint->get_con_from_hdl(hdl))
|
||||
endpoint->handler()->on_close (conn);
|
||||
});
|
||||
|
||||
endpoint->set_fail_handler (
|
||||
[endpoint] (websocketpp::connection_hdl hdl) {
|
||||
if (auto conn = endpoint->get_con_from_hdl(hdl))
|
||||
endpoint->handler()->on_fail (conn);
|
||||
});
|
||||
|
||||
endpoint->set_pong_handler (
|
||||
[endpoint] (websocketpp::connection_hdl hdl, std::string data) {
|
||||
if (auto conn = endpoint->get_con_from_hdl(hdl))
|
||||
endpoint->handler()->on_pong (conn, data);
|
||||
});
|
||||
|
||||
endpoint->set_http_handler (
|
||||
[endpoint] (websocketpp::connection_hdl hdl) {
|
||||
if (auto conn = endpoint->get_con_from_hdl(hdl))
|
||||
endpoint->handler()->http (conn);
|
||||
});
|
||||
|
||||
endpoint->set_message_handler (
|
||||
[endpoint] (websocketpp::connection_hdl hdl,
|
||||
MessagePtr msg) {
|
||||
if (auto conn = endpoint->get_con_from_hdl(hdl))
|
||||
endpoint->handler()->on_message (conn, msg);
|
||||
});
|
||||
|
||||
endpoint->set_send_empty_handler (
|
||||
[endpoint] (websocketpp::connection_hdl hdl) {
|
||||
if (auto conn = endpoint->get_con_from_hdl(hdl))
|
||||
endpoint->handler()->on_send_empty (conn);
|
||||
});
|
||||
|
||||
endpoint->init_asio();
|
||||
|
||||
return endpoint;
|
||||
}
|
||||
|
||||
template <>
|
||||
void ConnectionImpl <WebSocket04>::setPingTimer ()
|
||||
{
|
||||
if (auto con = m_connection.lock ())
|
||||
{
|
||||
auto t = boost::posix_time::seconds (getConfig ().WEBSOCKET_PING_FREQ);
|
||||
auto ms = t.total_milliseconds();
|
||||
con->set_timer (
|
||||
ms,
|
||||
[this] (WebSocket04::ErrorCode const& e)
|
||||
{
|
||||
this->pingTimer (e);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
boost::asio::io_service::strand& WebSocket04::getStrand (Connection& con)
|
||||
{
|
||||
return *con.get_strand();
|
||||
}
|
||||
|
||||
template <>
|
||||
void Server <WebSocket04>::listen()
|
||||
{
|
||||
m_endpoint->listen (desc_.port.ip, desc_.port.port);
|
||||
m_endpoint->start_accept();
|
||||
auto c = m_endpoint->get_io_service ().run ();
|
||||
WriteLog (lsWARNING, WebSocket)
|
||||
<< "Server run with: '" << c;
|
||||
|
||||
}
|
||||
|
||||
std::unique_ptr<beast::Stoppable> makeServer04 (ServerDescription const& desc)
|
||||
{
|
||||
return std::make_unique <Server <WebSocket04>> (desc);
|
||||
}
|
||||
|
||||
} // websocket
|
||||
} // ripple
|
||||
106
src/ripple/websocket/WebSocket04.h
Normal file
106
src/ripple/websocket/WebSocket04.h
Normal file
@@ -0,0 +1,106 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLED_RIPPLE_WEBSOCKET_WEBSOCKET04_H
|
||||
#define RIPPLED_RIPPLE_WEBSOCKET_WEBSOCKET04_H
|
||||
|
||||
#include <ripple/websocket/Config04.h>
|
||||
#include <ripple/websocket/WebSocket.h>
|
||||
|
||||
namespace ripple {
|
||||
namespace websocket {
|
||||
|
||||
struct WebSocket04
|
||||
{
|
||||
using EndpointBase = websocketpp::server <Config04>;
|
||||
|
||||
using Connection = EndpointBase::connection_type;
|
||||
using ConnectionPtr = std::shared_ptr<Connection>;
|
||||
using ConnectionWeakPtr = std::weak_ptr<Connection>;
|
||||
using ErrorCode = std::error_code;
|
||||
using Message = Connection::message_type;
|
||||
using MessagePtr = Message::ptr;
|
||||
|
||||
class Handler
|
||||
{
|
||||
public:
|
||||
virtual void on_open (ConnectionPtr) = 0;
|
||||
virtual void on_close (ConnectionPtr) = 0;
|
||||
virtual void on_fail (ConnectionPtr) = 0;
|
||||
virtual void on_pong (ConnectionPtr, std::string data) = 0;
|
||||
virtual bool http (ConnectionPtr) = 0;
|
||||
virtual void on_message (ConnectionPtr, MessagePtr) = 0;
|
||||
// This is a new method added by Ripple.
|
||||
virtual void on_send_empty (ConnectionPtr) = 0;
|
||||
};
|
||||
|
||||
using HandlerPtr = std::shared_ptr<Handler>;
|
||||
|
||||
class Endpoint : public EndpointBase
|
||||
{
|
||||
public:
|
||||
using ptr = std::shared_ptr<Endpoint>;
|
||||
|
||||
Endpoint (HandlerPtr handler) : handler_ (handler)
|
||||
{
|
||||
}
|
||||
|
||||
HandlerPtr const& handler() { return handler_; }
|
||||
|
||||
private:
|
||||
HandlerPtr handler_;
|
||||
};
|
||||
|
||||
using EndpointPtr = std::shared_ptr<Endpoint>;
|
||||
/** The name of this WebSocket version. */
|
||||
static
|
||||
char const* versionName();
|
||||
|
||||
/** Handle a connection that was cut off from the other side. */
|
||||
static
|
||||
void handleDisconnect (Connection&);
|
||||
|
||||
/** Close a client that is too slow to respond. */
|
||||
static
|
||||
void closeTooSlowClient (
|
||||
Connection&,
|
||||
unsigned int timeout,
|
||||
std::string const& message = "Client is too slow.");
|
||||
|
||||
/** Return true if the WebSocket message is a TEXT message. */
|
||||
static
|
||||
bool isTextMessage (Message const&);
|
||||
|
||||
/** Create a new Handler. */
|
||||
static
|
||||
HandlerPtr makeHandler (ServerDescription const&);
|
||||
|
||||
/** Make a connection endpoint from a handler. */
|
||||
static
|
||||
EndpointPtr makeEndpoint (HandlerPtr&&);
|
||||
|
||||
/** Get the ASIO strand that this connection lives on. */
|
||||
static
|
||||
boost::asio::io_service::strand& getStrand (Connection&);
|
||||
};
|
||||
|
||||
} // websocket
|
||||
} // ripple
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user