Updates from BitShares FC #22
3 changed files with 0 additions and 1036 deletions
|
|
@ -238,7 +238,6 @@ set( fc_sources
|
|||
src/interprocess/file_mapping.cpp
|
||||
src/rpc/cli.cpp
|
||||
src/rpc/http_api.cpp
|
||||
src/rpc/json_connection.cpp
|
||||
src/rpc/state.cpp
|
||||
src/rpc/websocket_api.cpp
|
||||
src/log/log_message.cpp
|
||||
|
|
|
|||
|
|
@ -1,318 +0,0 @@
|
|||
#pragma once
|
||||
#include <fc/io/buffered_iostream.hpp>
|
||||
#include <fc/variant_object.hpp>
|
||||
#include <fc/thread/future.hpp>
|
||||
#include <fc/log/logger.hpp>
|
||||
#include <functional>
|
||||
|
||||
namespace fc { namespace rpc {
|
||||
|
||||
namespace detail { class json_connection_impl; }
|
||||
|
||||
/**
|
||||
* @brief Implements JSON-RPC 2.0 over a set of io streams
|
||||
*
|
||||
* Each JSON RPC message is expected to be on its own line, violators
|
||||
* will be prosecuted to the fullest extent of the law.
|
||||
*/
|
||||
class json_connection
|
||||
{
|
||||
public:
|
||||
typedef std::function<variant(const variants&)> method;
|
||||
typedef std::function<variant(const variant_object&)> named_param_method;
|
||||
|
||||
json_connection( fc::buffered_istream_ptr in, fc::buffered_ostream_ptr out, uint32_t max_depth );
|
||||
~json_connection();
|
||||
|
||||
/**
|
||||
* Starts processing messages from input
|
||||
*/
|
||||
future<void> exec();
|
||||
|
||||
bool is_open();
|
||||
void close();
|
||||
|
||||
void set_on_disconnected_callback(std::function<void(fc::exception_ptr)> callback);
|
||||
|
||||
logger get_logger()const;
|
||||
void set_logger( const logger& l );
|
||||
|
||||
/**
|
||||
* @name server interface
|
||||
*
|
||||
* Adding methods to the interface allows the remote side
|
||||
* to call them.
|
||||
*/
|
||||
///@{
|
||||
void add_method( const std::string& name, method );
|
||||
void add_named_param_method( const std::string& name, named_param_method );
|
||||
void remove_method( const std::string& name );
|
||||
//@}
|
||||
|
||||
/**
|
||||
* @name client interface
|
||||
*/
|
||||
///@{
|
||||
void notice( const std::string& method );
|
||||
void notice( const std::string& method, const variants& args );
|
||||
void notice( const std::string& method, const variant_object& named_args );
|
||||
|
||||
/// args will be handled as named params
|
||||
future<variant> async_call( const std::string& method,
|
||||
const variant_object& args );
|
||||
|
||||
future<variant> async_call( const std::string& method, mutable_variant_object args );
|
||||
|
||||
/// Sending in an array of variants will be handled as positional arguments
|
||||
future<variant> async_call( const std::string& method,
|
||||
const variants& args );
|
||||
|
||||
future<variant> async_call( const std::string& method );
|
||||
|
||||
future<variant> async_call( const std::string& method,
|
||||
const variant& a1 );
|
||||
|
||||
future<variant> async_call( const std::string& method,
|
||||
const variant& a1,
|
||||
const variant& a2 );
|
||||
|
||||
future<variant> async_call( const std::string& method,
|
||||
const variant& a1,
|
||||
const variant& a2,
|
||||
const variant& a3 );
|
||||
|
||||
future<variant> async_call( const std::string& method,
|
||||
const variant& a1,
|
||||
const variant& a2,
|
||||
const variant& a3,
|
||||
const variant& a4 );
|
||||
|
||||
future<variant> async_call( const std::string& method,
|
||||
const variant& a1,
|
||||
const variant& a2,
|
||||
const variant& a3,
|
||||
const variant& a4,
|
||||
const variant& a5 );
|
||||
|
||||
future<variant> async_call( const std::string& method,
|
||||
const variant& a1,
|
||||
const variant& a2,
|
||||
const variant& a3,
|
||||
const variant& a4,
|
||||
const variant& a5,
|
||||
const variant& a6 );
|
||||
|
||||
future<variant> async_call( const std::string& method,
|
||||
const variant& a1,
|
||||
const variant& a2,
|
||||
const variant& a3,
|
||||
const variant& a4,
|
||||
const variant& a5,
|
||||
const variant& a6,
|
||||
const variant& a7
|
||||
);
|
||||
|
||||
future<variant> async_call( const std::string& method,
|
||||
const variant& a1,
|
||||
const variant& a2,
|
||||
const variant& a3,
|
||||
const variant& a4,
|
||||
const variant& a5,
|
||||
const variant& a6,
|
||||
const variant& a7,
|
||||
const variant& a8
|
||||
);
|
||||
future<variant> async_call( const std::string& method,
|
||||
const variant& a1,
|
||||
const variant& a2,
|
||||
const variant& a3,
|
||||
const variant& a4,
|
||||
const variant& a5,
|
||||
const variant& a6,
|
||||
const variant& a7,
|
||||
const variant& a8,
|
||||
const variant& a9
|
||||
);
|
||||
future<variant> async_call( const std::string& method,
|
||||
const variant& a1,
|
||||
const variant& a2,
|
||||
const variant& a3,
|
||||
const variant& a4,
|
||||
const variant& a5,
|
||||
const variant& a6,
|
||||
const variant& a7,
|
||||
const variant& a8,
|
||||
const variant& a9,
|
||||
const variant& a10
|
||||
);
|
||||
|
||||
template<typename Result>
|
||||
Result call( const std::string& method,
|
||||
const variants& args,
|
||||
microseconds timeout = microseconds::maximum())
|
||||
{
|
||||
return async_call( method, args ).wait(timeout).as<Result>();
|
||||
}
|
||||
|
||||
template<typename Result>
|
||||
Result call( const std::string& method,
|
||||
const variant& a1,
|
||||
const variant& a2,
|
||||
const variant& a3,
|
||||
microseconds timeout = microseconds::maximum())
|
||||
{
|
||||
return async_call( method, a1, a2, a3 ).wait(timeout).as<Result>();
|
||||
}
|
||||
|
||||
template<typename Result>
|
||||
Result call( const std::string& method,
|
||||
const variant& a1,
|
||||
const variant& a2,
|
||||
const variant& a3,
|
||||
const variant& a4,
|
||||
microseconds timeout = microseconds::maximum())
|
||||
{
|
||||
return async_call( method, a1, a2, a3, a4).wait(timeout).as<Result>();
|
||||
}
|
||||
|
||||
template<typename Result>
|
||||
Result call( const std::string& method,
|
||||
const variant& a1,
|
||||
const variant& a2,
|
||||
const variant& a3,
|
||||
const variant& a4,
|
||||
const variant& a5,
|
||||
microseconds timeout = microseconds::maximum())
|
||||
{
|
||||
return async_call( method, a1, a2, a3, a4, a5).wait(timeout).as<Result>();
|
||||
}
|
||||
|
||||
template<typename Result>
|
||||
Result call( const std::string& method,
|
||||
const variant& a1,
|
||||
const variant& a2,
|
||||
const variant& a3,
|
||||
const variant& a4,
|
||||
const variant& a5,
|
||||
const variant& a6,
|
||||
microseconds timeout = microseconds::maximum())
|
||||
{
|
||||
return async_call( method, a1, a2, a3, a4, a5, a6).wait(timeout).as<Result>();
|
||||
}
|
||||
template<typename Result>
|
||||
Result call( const std::string& method,
|
||||
const variant& a1,
|
||||
const variant& a2,
|
||||
const variant& a3,
|
||||
const variant& a4,
|
||||
const variant& a5,
|
||||
const variant& a6,
|
||||
const variant& a7,
|
||||
microseconds timeout = microseconds::maximum())
|
||||
{
|
||||
return async_call( method, a1, a2, a3, a4, a5, a6, a7).wait(timeout).as<Result>();
|
||||
}
|
||||
|
||||
template<typename Result>
|
||||
Result call( const std::string& method,
|
||||
const variant& a1,
|
||||
const variant& a2,
|
||||
const variant& a3,
|
||||
const variant& a4,
|
||||
const variant& a5,
|
||||
const variant& a6,
|
||||
const variant& a7,
|
||||
const variant& a8,
|
||||
microseconds timeout = microseconds::maximum())
|
||||
{
|
||||
return async_call( method, a1, a2, a3, a4, a5, a6, a7, a8).wait(timeout).as<Result>();
|
||||
}
|
||||
|
||||
template<typename Result>
|
||||
Result call( const std::string& method,
|
||||
const variant& a1,
|
||||
const variant& a2,
|
||||
const variant& a3,
|
||||
const variant& a4,
|
||||
const variant& a5,
|
||||
const variant& a6,
|
||||
const variant& a7,
|
||||
const variant& a8,
|
||||
const variant& a9,
|
||||
microseconds timeout = microseconds::maximum())
|
||||
{
|
||||
return async_call( method, a1, a2, a3, a4, a5, a6, a7, a8, a9).wait(timeout).as<Result>();
|
||||
}
|
||||
|
||||
template<typename Result>
|
||||
Result call( const std::string& method,
|
||||
const variant& a1,
|
||||
const variant& a2,
|
||||
const variant& a3,
|
||||
const variant& a4,
|
||||
const variant& a5,
|
||||
const variant& a6,
|
||||
const variant& a7,
|
||||
const variant& a8,
|
||||
const variant& a9,
|
||||
const variant& a10,
|
||||
microseconds timeout = microseconds::maximum())
|
||||
{
|
||||
return async_call( method, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10).wait(timeout).as<Result>();
|
||||
}
|
||||
|
||||
template<typename Result>
|
||||
Result call( const std::string& method,
|
||||
const variant& a1,
|
||||
const variant& a2,
|
||||
microseconds timeout = microseconds::maximum())
|
||||
{
|
||||
return async_call( method, a1, a2 ).wait(timeout).as<Result>();
|
||||
}
|
||||
|
||||
template<typename Result>
|
||||
Result call( const std::string& method,
|
||||
const variant& a1,
|
||||
microseconds timeout = microseconds::maximum())
|
||||
{
|
||||
return async_call( method, a1 ).wait(timeout).as<Result>();
|
||||
}
|
||||
|
||||
template<typename Result>
|
||||
Result call( const std::string& method,
|
||||
variant_object a1,
|
||||
microseconds timeout = microseconds::maximum())
|
||||
{
|
||||
return async_call( method, std::move(a1) ).wait(timeout).as<Result>();
|
||||
}
|
||||
template<typename Result>
|
||||
Result call( const std::string& method,
|
||||
mutable_variant_object a1,
|
||||
microseconds timeout = microseconds::maximum())
|
||||
{
|
||||
return async_call( method, variant_object( std::move(a1) ) ).wait(timeout).as<Result>();
|
||||
}
|
||||
|
||||
|
||||
template<typename Result>
|
||||
Result call( const std::string& method, microseconds timeout = microseconds::maximum() )
|
||||
{
|
||||
return async_call( method ).wait(timeout).as<Result>();
|
||||
}
|
||||
|
||||
/// Sending in a variant_object will be issued as named parameters
|
||||
variant call( const std::string& method, const variant_object& named_args );
|
||||
///@}
|
||||
|
||||
protected:
|
||||
const uint32_t _max_conversion_depth; // for nested structures, json, variant etc.
|
||||
|
||||
private:
|
||||
std::unique_ptr<detail::json_connection_impl> my;
|
||||
};
|
||||
typedef std::shared_ptr<json_connection> json_connection_ptr;
|
||||
|
||||
}} // fc::rpc
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,717 +0,0 @@
|
|||
#include <fc/rpc/json_connection.hpp>
|
||||
#include <fc/io/json.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include <fc/thread/thread.hpp>
|
||||
#include <fc/thread/scoped_lock.hpp>
|
||||
#include <fc/thread/mutex.hpp>
|
||||
#include <fc/log/logger.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace fc { namespace rpc {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
class json_connection_impl
|
||||
{
|
||||
public:
|
||||
json_connection_impl( fc::buffered_istream_ptr&& in, fc::buffered_ostream_ptr&& out, uint32_t max_depth )
|
||||
:_in(std::move(in)),_out(std::move(out)),_eof(false),_next_id(0),_logger("json_connection"),_max_depth(max_depth){}
|
||||
|
||||
fc::buffered_istream_ptr _in;
|
||||
fc::buffered_ostream_ptr _out;
|
||||
|
||||
fc::future<void> _done;
|
||||
fc::future<void> _handle_message_future;
|
||||
bool _eof;
|
||||
|
||||
uint64_t _next_id;
|
||||
boost::unordered_map<uint64_t, fc::promise<variant>::ptr> _awaiting;
|
||||
boost::unordered_map<std::string, json_connection::method> _methods;
|
||||
boost::unordered_map<std::string, json_connection::named_param_method> _named_param_methods;
|
||||
|
||||
fc::mutex _write_mutex;
|
||||
std::function<void(fc::exception_ptr)> _on_close;
|
||||
|
||||
logger _logger;
|
||||
uint32_t _max_depth;
|
||||
|
||||
void send_result( variant id, variant result )
|
||||
{
|
||||
ilog( "send: {\"id\": ${i}, \"result\": ${r}}", ("i",id)("r",result) );
|
||||
{
|
||||
fc::scoped_lock<fc::mutex> lock(_write_mutex);
|
||||
*_out << "{\"id\":";
|
||||
json::to_stream( *_out, id, json::stringify_large_ints_and_doubles, _max_depth );
|
||||
*_out << ",\"result\":";
|
||||
json::to_stream( *_out, result, json::stringify_large_ints_and_doubles, _max_depth );
|
||||
*_out << "}\n";
|
||||
_out->flush();
|
||||
}
|
||||
}
|
||||
void send_error( variant id, fc::exception& e )
|
||||
{
|
||||
ilog( "send: {\"id\": ${i}, \"error\":{\"message\": ${what},\"code\":0,\"data\":${data}}}",
|
||||
("i",id)("what",e.what())("data", e) );
|
||||
{
|
||||
fc::scoped_lock<fc::mutex> lock(_write_mutex);
|
||||
*_out << "{\"id\":";
|
||||
json::to_stream( *_out, id, json::stringify_large_ints_and_doubles, _max_depth );
|
||||
*_out << ",\"error\":{\"message\":";
|
||||
json::to_stream( *_out, std::string(e.what()) );
|
||||
*_out <<",\"code\":0,\"data\":";
|
||||
json::to_stream( *_out, variant(e, _max_depth), json::stringify_large_ints_and_doubles, _max_depth );
|
||||
*_out << "}}\n";
|
||||
_out->flush();
|
||||
}
|
||||
//wlog( "exception: ${except}", ("except", variant(e)) );
|
||||
}
|
||||
|
||||
void handle_message( const variant_object& obj )
|
||||
{
|
||||
wlog( "recv: ${msg}", ("msg", obj) );
|
||||
fc::exception_ptr eptr;
|
||||
try
|
||||
{
|
||||
auto m = obj.find("method");
|
||||
auto i = obj.find("id");
|
||||
if( m != obj.end() )
|
||||
{
|
||||
fc::exception except;
|
||||
bool exception_caught = false;
|
||||
try
|
||||
{
|
||||
auto p = obj.find("params");
|
||||
variant result;
|
||||
if( p == obj.end() )
|
||||
{
|
||||
auto pmi = _methods.find(m->value().as_string());
|
||||
auto nmi = _named_param_methods.find(m->value().as_string());
|
||||
if( pmi != _methods.end() )
|
||||
{
|
||||
result = pmi->second( variants() );
|
||||
}
|
||||
else if( nmi != _named_param_methods.end() )
|
||||
{
|
||||
result = nmi->second( variant_object() );
|
||||
}
|
||||
else // invalid method
|
||||
{
|
||||
FC_THROW_EXCEPTION( exception, "Invalid Method '${method}'", ("method",m->value().as_string()));
|
||||
}
|
||||
}
|
||||
else if( p->value().is_array() )
|
||||
{
|
||||
auto pmi = _methods.find(m->value().as_string());
|
||||
if( pmi != _methods.end() )
|
||||
{
|
||||
result = pmi->second( p->value().get_array() );
|
||||
}
|
||||
else // invalid method / param combo
|
||||
{
|
||||
FC_THROW_EXCEPTION( exception, "Invalid method or params '${method}'",
|
||||
("method",m->value().as_string()));
|
||||
}
|
||||
|
||||
}
|
||||
else if( p->value().is_object() )
|
||||
{
|
||||
auto nmi = _named_param_methods.find(m->value().as_string());
|
||||
if( nmi != _named_param_methods.end() )
|
||||
{
|
||||
result = nmi->second( p->value().get_object() );
|
||||
}
|
||||
else // invalid method / param combo?
|
||||
{
|
||||
FC_THROW_EXCEPTION( exception, "Invalid method or params '${method}'",
|
||||
("method",m->value().as_string()));
|
||||
}
|
||||
}
|
||||
else // invalid params
|
||||
{
|
||||
FC_THROW_EXCEPTION( exception, "Invalid Params for method ${method}",
|
||||
("method",m->value().as_string()));
|
||||
}
|
||||
if( i != obj.end() )
|
||||
{
|
||||
send_result( i->value(), result );
|
||||
}
|
||||
}
|
||||
catch ( fc::exception& e )
|
||||
{
|
||||
exception_caught = true;
|
||||
except = e;
|
||||
}
|
||||
if( exception_caught && i != obj.end() )
|
||||
send_error( i->value(), except );
|
||||
else
|
||||
fc_wlog( _logger, "json rpc exception: ${exception}", ("exception",except) );
|
||||
}
|
||||
else if( i != obj.end() ) //handle any received JSON response
|
||||
{
|
||||
uint64_t id = i->value().as_int64();
|
||||
auto await = _awaiting.find(id);
|
||||
if( await != _awaiting.end() )
|
||||
{
|
||||
auto r = obj.find("result");
|
||||
auto e = obj.find("error");
|
||||
if( r != obj.end() ) //if regular result response
|
||||
{
|
||||
await->second->set_value( r->value() );
|
||||
}
|
||||
else if( e != obj.end() ) //if error response
|
||||
{
|
||||
fc::exception_ptr eptr;
|
||||
try
|
||||
{
|
||||
auto err = e->value().get_object();
|
||||
auto data = err.find( "data" );
|
||||
if( data != err.end() )
|
||||
await->second->set_exception( data->value().as<exception>(_max_depth).dynamic_copy_exception() );
|
||||
else
|
||||
await->second->set_exception( exception_ptr(new FC_EXCEPTION( exception, "${error}", ("error",e->value()) ) ) );
|
||||
}
|
||||
catch ( fc::exception& e )
|
||||
{
|
||||
elog( "Error parsing exception: ${e}", ("e", e.to_detail_string() ) );
|
||||
eptr = e.dynamic_copy_exception();
|
||||
}
|
||||
if( eptr ) await->second->set_exception( eptr );
|
||||
}
|
||||
else // id found without error, result, nor method field
|
||||
{
|
||||
fc_wlog( _logger, "no error or result specified in '${message}'", ("message",obj) );
|
||||
}
|
||||
}
|
||||
}
|
||||
else // no method nor request id... invalid message
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
catch ( fc::exception& e ) // catch all other errors...
|
||||
{
|
||||
fc_elog( _logger, "json rpc exception: ${exception}", ("exception",e ));
|
||||
elog( "json rpc exception: ${exception}", ("exception",e ));
|
||||
eptr = e.dynamic_copy_exception();
|
||||
}
|
||||
if( eptr ) { close(eptr); }
|
||||
}
|
||||
|
||||
void read_loop()
|
||||
{
|
||||
fc::exception_ptr eptr;
|
||||
try
|
||||
{
|
||||
std::string line;
|
||||
while( !_done.canceled() )
|
||||
{
|
||||
variant v = json::from_stream( *_in, json::legacy_parser, _max_depth );
|
||||
///ilog( "input: ${in}", ("in", v ) );
|
||||
//wlog( "recv: ${line}", ("line", line) );
|
||||
_handle_message_future = fc::async([=](){ handle_message(v.get_object()); }, "json_connection handle_message");
|
||||
}
|
||||
}
|
||||
catch ( eof_exception& eof )
|
||||
{
|
||||
_eof = true;
|
||||
eptr = eof.dynamic_copy_exception();
|
||||
}
|
||||
catch ( exception& e )
|
||||
{
|
||||
eptr = e.dynamic_copy_exception();
|
||||
}
|
||||
catch ( ... )
|
||||
{
|
||||
eptr = fc::exception_ptr(new FC_EXCEPTION( unhandled_exception, "json connection read error" ));
|
||||
}
|
||||
if( eptr ) close( eptr );
|
||||
}
|
||||
|
||||
void close( fc::exception_ptr e )
|
||||
{
|
||||
wlog( "close ${reason}", ("reason", e->to_detail_string() ) );
|
||||
if( _on_close )
|
||||
_on_close(e);
|
||||
for( auto itr = _awaiting.begin(); itr != _awaiting.end(); ++itr )
|
||||
{
|
||||
itr->second->set_exception( e->dynamic_copy_exception() );
|
||||
}
|
||||
}
|
||||
};
|
||||
}//namespace detail
|
||||
|
||||
json_connection::json_connection( fc::buffered_istream_ptr in, fc::buffered_ostream_ptr out, uint32_t max_depth )
|
||||
:_max_conversion_depth(max_depth),my( new detail::json_connection_impl(std::move(in),std::move(out),max_depth) )
|
||||
{}
|
||||
|
||||
json_connection::~json_connection()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
fc::future<void> json_connection::exec()
|
||||
{
|
||||
if( my->_done.valid() )
|
||||
{
|
||||
FC_THROW_EXCEPTION( assert_exception, "start should only be called once" );
|
||||
}
|
||||
return my->_done = fc::async( [=](){ my->read_loop(); }, "json_connection read_loop" );
|
||||
}
|
||||
|
||||
void json_connection::close()
|
||||
{
|
||||
try
|
||||
{
|
||||
if( my->_handle_message_future.valid() && !my->_handle_message_future.ready() )
|
||||
my->_handle_message_future.cancel_and_wait(__FUNCTION__);
|
||||
if( my->_done.valid() && !my->_done.ready() )
|
||||
{
|
||||
my->_done.cancel("json_connection is destructing");
|
||||
my->_out->close();
|
||||
my->_done.wait();
|
||||
}
|
||||
}
|
||||
catch ( fc::canceled_exception& ){} // expected exception
|
||||
catch ( fc::eof_exception& ){} // expected exception
|
||||
catch ( fc::exception& e )
|
||||
{
|
||||
// unhandled, unexpected exception cannot throw from destructor, so log it.
|
||||
wlog( "${exception}", ("exception",e.to_detail_string()) );
|
||||
}
|
||||
}
|
||||
|
||||
void json_connection::set_on_disconnected_callback(std::function<void (exception_ptr)> callback)
|
||||
{
|
||||
my->_on_close = callback;
|
||||
}
|
||||
|
||||
void json_connection::add_method( const std::string& name, method m )
|
||||
{
|
||||
ilog( "add method ${name}", ("name",name) );
|
||||
my->_methods.emplace(std::pair<std::string,method>(name,std::move(m)));
|
||||
}
|
||||
void json_connection::add_named_param_method( const std::string& name, named_param_method m )
|
||||
{
|
||||
ilog( "add named param method ${name}", ("name",name) );
|
||||
my->_named_param_methods.emplace(std::pair<std::string,named_param_method>(name,std::move(m)));
|
||||
}
|
||||
void json_connection::remove_method( const std::string& name )
|
||||
{
|
||||
my->_methods.erase(name);
|
||||
my->_named_param_methods.erase(name);
|
||||
}
|
||||
void json_connection::notice( const std::string& method, const variants& args )
|
||||
{
|
||||
fc::scoped_lock<fc::mutex> lock(my->_write_mutex);
|
||||
*my->_out << "{\"method\":";
|
||||
json::to_stream( *my->_out, method );
|
||||
if( args.size() )
|
||||
{
|
||||
*my->_out << ",\"params\":";
|
||||
fc::json::to_stream( *my->_out, args );
|
||||
*my->_out << "}\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
*my->_out << ",\"params\":[]}\n";
|
||||
}
|
||||
}
|
||||
void json_connection::notice( const std::string& method, const variant_object& named_args )
|
||||
{
|
||||
{
|
||||
fc::scoped_lock<fc::mutex> lock(my->_write_mutex);
|
||||
*my->_out << "{\"method\":";
|
||||
json::to_stream( *my->_out, method );
|
||||
*my->_out << ",\"params\":";
|
||||
fc::json::to_stream( *my->_out, named_args );
|
||||
*my->_out << "}\n";
|
||||
my->_out->flush();
|
||||
}
|
||||
}
|
||||
void json_connection::notice( const std::string& method )
|
||||
{
|
||||
{
|
||||
fc::scoped_lock<fc::mutex> lock(my->_write_mutex);
|
||||
*my->_out << "{\"method\":";
|
||||
json::to_stream( *my->_out, method );
|
||||
*my->_out << "}\n";
|
||||
my->_out->flush();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
future<variant> json_connection::async_call( const std::string& method, const variants& args )
|
||||
{
|
||||
auto id = my->_next_id++;
|
||||
my->_awaiting[id] = fc::promise<variant>::ptr( new fc::promise<variant>("json_connection::async_call") );
|
||||
|
||||
{
|
||||
fc::scoped_lock<fc::mutex> lock(my->_write_mutex);
|
||||
*my->_out << "{\"id\":";
|
||||
*my->_out << id;
|
||||
*my->_out << ",\"method\":";
|
||||
json::to_stream( *my->_out, method );
|
||||
if( args.size() )
|
||||
{
|
||||
*my->_out << ",\"params\":";
|
||||
fc::json::to_stream( *my->_out, args );
|
||||
*my->_out << "}\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
*my->_out << ",\"params\":[]}\n";
|
||||
}
|
||||
my->_out->flush();
|
||||
}
|
||||
return my->_awaiting[id];
|
||||
}
|
||||
|
||||
future<variant> json_connection::async_call( const std::string& method, const variant& a1 )
|
||||
{
|
||||
auto id = my->_next_id++;
|
||||
my->_awaiting[id] = fc::promise<variant>::ptr( new fc::promise<variant>("json_connection::async_call") );
|
||||
|
||||
{
|
||||
fc::scoped_lock<fc::mutex> lock(my->_write_mutex);
|
||||
*my->_out << "{\"id\":";
|
||||
*my->_out << id;
|
||||
*my->_out << ",\"method\":";
|
||||
json::to_stream( *my->_out, method );
|
||||
*my->_out << ",\"params\":[";
|
||||
fc::json::to_stream( *my->_out, a1 );
|
||||
*my->_out << "]}\n";
|
||||
my->_out->flush();
|
||||
}
|
||||
return my->_awaiting[id];
|
||||
}
|
||||
future<variant> json_connection::async_call( const std::string& method, const variant& a1, const variant& a2 )
|
||||
{
|
||||
auto id = my->_next_id++;
|
||||
my->_awaiting[id] = fc::promise<variant>::ptr( new fc::promise<variant>("json_connection::async_call") );
|
||||
|
||||
{
|
||||
fc::scoped_lock<fc::mutex> lock(my->_write_mutex);
|
||||
*my->_out << "{\"id\":";
|
||||
*my->_out << id;
|
||||
*my->_out << ",\"method\":";
|
||||
json::to_stream( *my->_out, method );
|
||||
*my->_out << ",\"params\":[";
|
||||
fc::json::to_stream( *my->_out, a1 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a2 );
|
||||
*my->_out << "]}\n";
|
||||
my->_out->flush();
|
||||
}
|
||||
return my->_awaiting[id];
|
||||
}
|
||||
future<variant> json_connection::async_call( const std::string& method, const variant& a1, const variant& a2, const variant& a3 )
|
||||
{
|
||||
auto id = my->_next_id++;
|
||||
my->_awaiting[id] = fc::promise<variant>::ptr( new fc::promise<variant>("json_connection::async_call") );
|
||||
|
||||
{
|
||||
fc::scoped_lock<fc::mutex> lock(my->_write_mutex);
|
||||
*my->_out << "{\"id\":";
|
||||
*my->_out << id;
|
||||
*my->_out << ",\"method\":";
|
||||
json::to_stream( *my->_out, method );
|
||||
*my->_out << ",\"params\":[";
|
||||
fc::json::to_stream( *my->_out, a1 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a2 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a3 );
|
||||
*my->_out << "]}\n";
|
||||
my->_out->flush();
|
||||
}
|
||||
return my->_awaiting[id];
|
||||
}
|
||||
|
||||
future<variant> json_connection::async_call( const std::string& method, const variant& a1, const variant& a2, const variant& a3, const variant& a4 )
|
||||
{
|
||||
auto id = my->_next_id++;
|
||||
my->_awaiting[id] = fc::promise<variant>::ptr( new fc::promise<variant>("json_connection::async_call") );
|
||||
|
||||
{
|
||||
fc::scoped_lock<fc::mutex> lock(my->_write_mutex);
|
||||
*my->_out << "{\"id\":";
|
||||
*my->_out << id;
|
||||
*my->_out << ",\"method\":";
|
||||
json::to_stream( *my->_out, method );
|
||||
*my->_out << ",\"params\":[";
|
||||
fc::json::to_stream( *my->_out, a1 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a2 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a3 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a4 );
|
||||
*my->_out << "]}\n";
|
||||
my->_out->flush();
|
||||
}
|
||||
return my->_awaiting[id];
|
||||
}
|
||||
|
||||
future<variant> json_connection::async_call( const std::string& method, const variant& a1, const variant& a2, const variant& a3, const variant& a4, const variant& a5 )
|
||||
{
|
||||
auto id = my->_next_id++;
|
||||
my->_awaiting[id] = fc::promise<variant>::ptr( new fc::promise<variant>("json_connection::async_call") );
|
||||
|
||||
{
|
||||
fc::scoped_lock<fc::mutex> lock(my->_write_mutex);
|
||||
*my->_out << "{\"id\":";
|
||||
*my->_out << id;
|
||||
*my->_out << ",\"method\":";
|
||||
json::to_stream( *my->_out, method );
|
||||
*my->_out << ",\"params\":[";
|
||||
fc::json::to_stream( *my->_out, a1 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a2 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a3 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a4 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a5 );
|
||||
*my->_out << "]}\n";
|
||||
my->_out->flush();
|
||||
}
|
||||
return my->_awaiting[id];
|
||||
}
|
||||
|
||||
future<variant> json_connection::async_call( const std::string& method, const variant& a1, const variant& a2, const variant& a3, const variant& a4, const variant& a5, const variant& a6 )
|
||||
{
|
||||
auto id = my->_next_id++;
|
||||
my->_awaiting[id] = fc::promise<variant>::ptr( new fc::promise<variant>("json_connection::async_call") );
|
||||
|
||||
{
|
||||
fc::scoped_lock<fc::mutex> lock(my->_write_mutex);
|
||||
*my->_out << "{\"id\":";
|
||||
*my->_out << id;
|
||||
*my->_out << ",\"method\":";
|
||||
json::to_stream( *my->_out, method );
|
||||
*my->_out << ",\"params\":[";
|
||||
fc::json::to_stream( *my->_out, a1 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a2 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a3 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a4 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a5 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a6 );
|
||||
*my->_out << "]}\n";
|
||||
my->_out->flush();
|
||||
}
|
||||
return my->_awaiting[id];
|
||||
}
|
||||
future<variant> json_connection::async_call( const std::string& method, const variant& a1, const variant& a2, const variant& a3, const variant& a4, const variant& a5, const variant& a6, const variant& a7 )
|
||||
{
|
||||
auto id = my->_next_id++;
|
||||
my->_awaiting[id] = fc::promise<variant>::ptr( new fc::promise<variant>("json_connection::async_call") );
|
||||
|
||||
{
|
||||
fc::scoped_lock<fc::mutex> lock(my->_write_mutex);
|
||||
*my->_out << "{\"id\":";
|
||||
*my->_out << id;
|
||||
*my->_out << ",\"method\":";
|
||||
json::to_stream( *my->_out, method );
|
||||
*my->_out << ",\"params\":[";
|
||||
fc::json::to_stream( *my->_out, a1 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a2 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a3 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a4 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a5 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a6 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a7 );
|
||||
*my->_out << "]}\n";
|
||||
my->_out->flush();
|
||||
}
|
||||
return my->_awaiting[id];
|
||||
}
|
||||
future<variant> json_connection::async_call( const std::string& method,
|
||||
const variant& a1,
|
||||
const variant& a2,
|
||||
const variant& a3,
|
||||
const variant& a4,
|
||||
const variant& a5,
|
||||
const variant& a6,
|
||||
const variant& a7,
|
||||
const variant& a8 )
|
||||
{
|
||||
auto id = my->_next_id++;
|
||||
my->_awaiting[id] = fc::promise<variant>::ptr( new fc::promise<variant>("json_connection::async_call") );
|
||||
|
||||
{
|
||||
fc::scoped_lock<fc::mutex> lock(my->_write_mutex);
|
||||
*my->_out << "{\"id\":";
|
||||
*my->_out << id;
|
||||
*my->_out << ",\"method\":";
|
||||
json::to_stream( *my->_out, method );
|
||||
*my->_out << ",\"params\":[";
|
||||
fc::json::to_stream( *my->_out, a1 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a2 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a3 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a4 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a5 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a6 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a7 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a8 );
|
||||
*my->_out << "]}\n";
|
||||
my->_out->flush();
|
||||
}
|
||||
return my->_awaiting[id];
|
||||
}
|
||||
future<variant> json_connection::async_call( const std::string& method,
|
||||
const variant& a1,
|
||||
const variant& a2,
|
||||
const variant& a3,
|
||||
const variant& a4,
|
||||
const variant& a5,
|
||||
const variant& a6,
|
||||
const variant& a7,
|
||||
const variant& a8,
|
||||
const variant& a9 )
|
||||
{
|
||||
auto id = my->_next_id++;
|
||||
my->_awaiting[id] = fc::promise<variant>::ptr( new fc::promise<variant>("json_connection::async_call") );
|
||||
|
||||
{
|
||||
fc::scoped_lock<fc::mutex> lock(my->_write_mutex);
|
||||
*my->_out << "{\"id\":";
|
||||
*my->_out << id;
|
||||
*my->_out << ",\"method\":";
|
||||
json::to_stream( *my->_out, method );
|
||||
*my->_out << ",\"params\":[";
|
||||
fc::json::to_stream( *my->_out, a1 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a2 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a3 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a4 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a5 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a6 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a7 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a8 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a9 );
|
||||
*my->_out << "]}\n";
|
||||
my->_out->flush();
|
||||
}
|
||||
return my->_awaiting[id];
|
||||
}
|
||||
future<variant> json_connection::async_call( const std::string& method,
|
||||
const variant& a1,
|
||||
const variant& a2,
|
||||
const variant& a3,
|
||||
const variant& a4,
|
||||
const variant& a5,
|
||||
const variant& a6,
|
||||
const variant& a7,
|
||||
const variant& a8,
|
||||
const variant& a9,
|
||||
const variant& a10 )
|
||||
{
|
||||
auto id = my->_next_id++;
|
||||
my->_awaiting[id] = fc::promise<variant>::ptr( new fc::promise<variant>("json_connection::async_call") );
|
||||
|
||||
{
|
||||
fc::scoped_lock<fc::mutex> lock(my->_write_mutex);
|
||||
*my->_out << "{\"id\":";
|
||||
*my->_out << id;
|
||||
*my->_out << ",\"method\":";
|
||||
json::to_stream( *my->_out, method );
|
||||
*my->_out << ",\"params\":[";
|
||||
fc::json::to_stream( *my->_out, a1 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a2 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a3 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a4 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a5 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a6 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a7 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a8 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a9 );
|
||||
*my->_out << ",";
|
||||
fc::json::to_stream( *my->_out, a10 );
|
||||
*my->_out << "]}\n";
|
||||
my->_out->flush();
|
||||
}
|
||||
return my->_awaiting[id];
|
||||
}
|
||||
|
||||
future<variant> json_connection::async_call( const std::string& method, mutable_variant_object named_args )
|
||||
{
|
||||
return async_call( method, variant_object( std::move(named_args) ) );
|
||||
}
|
||||
future<variant> json_connection::async_call( const std::string& method, const variant_object& named_args )
|
||||
{
|
||||
auto id = my->_next_id++;
|
||||
my->_awaiting[id] = fc::promise<variant>::ptr( new fc::promise<variant>("json_connection::async_call") );
|
||||
fc::scoped_lock<fc::mutex> lock(my->_write_mutex);
|
||||
{
|
||||
*my->_out << "{\"id\":";
|
||||
*my->_out << id;
|
||||
*my->_out << ",\"method\":";
|
||||
json::to_stream( *my->_out, method );
|
||||
*my->_out << ",\"params\":";
|
||||
fc::json::to_stream( *my->_out, named_args );
|
||||
*my->_out << "}\n";
|
||||
my->_out->flush();
|
||||
}
|
||||
return my->_awaiting[id];
|
||||
}
|
||||
future<variant> json_connection::async_call( const std::string& method )
|
||||
{
|
||||
auto id = my->_next_id++;
|
||||
my->_awaiting[id] = fc::promise<variant>::ptr( new fc::promise<variant>("json_connection::async_call") );
|
||||
fc::scoped_lock<fc::mutex> lock(my->_write_mutex);
|
||||
{
|
||||
*my->_out << "{\"id\":";
|
||||
*my->_out << id;
|
||||
*my->_out << ",\"method\":";
|
||||
json::to_stream( *my->_out, method );
|
||||
*my->_out << "}\n";
|
||||
my->_out->flush();
|
||||
}
|
||||
return my->_awaiting[id];
|
||||
}
|
||||
|
||||
logger json_connection::get_logger()const
|
||||
{
|
||||
return my->_logger;
|
||||
}
|
||||
|
||||
void json_connection::set_logger( const logger& l )
|
||||
{
|
||||
my->_logger = l;
|
||||
}
|
||||
|
||||
}}
|
||||
Loading…
Reference in a new issue