better close notification and error handling
This commit is contained in:
parent
8b5e2e7613
commit
c8200afade
6 changed files with 15 additions and 6 deletions
|
|
@ -4,6 +4,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <fc/any.hpp>
|
#include <fc/any.hpp>
|
||||||
#include <fc/network/ip.hpp>
|
#include <fc/network/ip.hpp>
|
||||||
|
#include <fc/signals.hpp>
|
||||||
|
|
||||||
namespace fc { namespace http {
|
namespace fc { namespace http {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
@ -23,6 +24,8 @@ namespace fc { namespace http {
|
||||||
|
|
||||||
void set_session_data( fc::any d ){ _session_data = std::move(d); }
|
void set_session_data( fc::any d ){ _session_data = std::move(d); }
|
||||||
fc::any& get_session_data() { return _session_data; }
|
fc::any& get_session_data() { return _session_data; }
|
||||||
|
|
||||||
|
fc::signal<void()> closed;
|
||||||
private:
|
private:
|
||||||
fc::any _session_data;
|
fc::any _session_data;
|
||||||
std::function<void(const std::string&)> _on_message;
|
std::function<void(const std::string&)> _on_message;
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,7 @@ namespace fc {
|
||||||
variant call( const string& name, const variants& args )
|
variant call( const string& name, const variants& args )
|
||||||
{
|
{
|
||||||
auto itr = _by_name.find(name);
|
auto itr = _by_name.find(name);
|
||||||
FC_ASSERT( itr != _by_name.end() );
|
FC_ASSERT( itr != _by_name.end(), "no method with name '${name}'", ("name",name)("api",_by_name) );
|
||||||
return call( itr->second, args );
|
return call( itr->second, args );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -220,6 +220,7 @@ namespace fc {
|
||||||
return _local_callbacks.size() - 1;
|
return _local_callbacks.size() - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fc::signal<void()> closed;
|
||||||
private:
|
private:
|
||||||
std::vector< std::unique_ptr<generic_api> > _local_apis;
|
std::vector< std::unique_ptr<generic_api> > _local_apis;
|
||||||
std::map< uint64_t, api_id_type > _handle_to_id;
|
std::map< uint64_t, api_id_type > _handle_to_id;
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ namespace fc { namespace rpc {
|
||||||
}
|
}
|
||||||
catch ( const fc::exception& e )
|
catch ( const fc::exception& e )
|
||||||
{
|
{
|
||||||
edump((e.to_detail_string()));
|
std::cout << e.to_detail_string() << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ namespace fc { namespace rpc {
|
||||||
});
|
});
|
||||||
|
|
||||||
_connection.on_message_handler( [&]( const std::string& msg ){ on_message(msg); } );
|
_connection.on_message_handler( [&]( const std::string& msg ){ on_message(msg); } );
|
||||||
|
_connection.closed.connect( [this](){ closed(); } );
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual variant send_call( api_id_type api_id,
|
virtual variant send_call( api_id_type api_id,
|
||||||
|
|
@ -59,6 +60,7 @@ namespace fc { namespace rpc {
|
||||||
_connection.send_message( fc::json::to_string(req) );
|
_connection.send_message( fc::json::to_string(req) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void on_message( const std::string& message )
|
void on_message( const std::string& message )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,8 @@ namespace fc { namespace http {
|
||||||
|
|
||||||
virtual void send_message( const std::string& message )override
|
virtual void send_message( const std::string& message )override
|
||||||
{
|
{
|
||||||
_ws_connection->send( message );
|
auto ec = _ws_connection->send( message );
|
||||||
|
FC_ASSERT( !ec, "websocket send failed: ${msg}", ("msg",ec.message() ) );
|
||||||
}
|
}
|
||||||
virtual void close( int64_t code, const std::string& reason )override
|
virtual void close( int64_t code, const std::string& reason )override
|
||||||
{
|
{
|
||||||
|
|
@ -158,13 +159,15 @@ namespace fc { namespace http {
|
||||||
}).wait();
|
}).wait();
|
||||||
});
|
});
|
||||||
_client.set_close_handler( [=]( connection_hdl hdl ){
|
_client.set_close_handler( [=]( connection_hdl hdl ){
|
||||||
_client_thread.async( [&](){ _connection.reset(); } ).wait();
|
if( _connection )
|
||||||
|
_client_thread.async( [&](){ if( _connection ) _connection->closed(); _connection.reset(); } ).wait();
|
||||||
if( _closed ) _closed->set_value();
|
if( _closed ) _closed->set_value();
|
||||||
});
|
});
|
||||||
_client.set_fail_handler( [=]( connection_hdl hdl ){
|
_client.set_fail_handler( [=]( connection_hdl hdl ){
|
||||||
auto con = _client.get_con_from_hdl(hdl);
|
auto con = _client.get_con_from_hdl(hdl);
|
||||||
auto message = con->get_ec().message();
|
auto message = con->get_ec().message();
|
||||||
_client_thread.async( [&](){ _connection.reset(); } ).wait();
|
if( _connection )
|
||||||
|
_client_thread.async( [&](){ if( _connection ) _connection->closed(); _connection.reset(); } ).wait();
|
||||||
if( _connected && !_connected->ready() )
|
if( _connected && !_connected->ready() )
|
||||||
_connected->set_exception( exception_ptr( new FC_EXCEPTION( exception, "${message}", ("message",message)) ) );
|
_connected->set_exception( exception_ptr( new FC_EXCEPTION( exception, "${message}", ("message",message)) ) );
|
||||||
if( _closed )
|
if( _closed )
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ void state::handle_reply( const response& response )
|
||||||
await->second->set_value( *response.result );
|
await->second->set_value( *response.result );
|
||||||
else if( response.error )
|
else if( response.error )
|
||||||
{
|
{
|
||||||
await->second->set_exception( exception_ptr(new FC_EXCEPTION( exception, "${error}", ("error",*response.error) ) ) );
|
await->second->set_exception( exception_ptr(new FC_EXCEPTION( exception, "${error}", ("error",response.error->message)("data",response) ) ) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
await->second->set_value( fc::variant() );
|
await->second->set_value( fc::variant() );
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue