MACE
1.0.0
|
00001 #ifndef _MACE_RPC_DETAIL_CONNECTION_BASE_HPP_ 00002 #define _MACE_RPC_DETAIL_CONNECTION_BASE_HPP_ 00003 #include <mace/rpc/connection_base.hpp> 00004 #include <boost/unordered_map.hpp> 00005 #include <boost/lexical_cast.hpp> 00006 00007 namespace mace { namespace rpc { namespace detail { 00008 typedef boost::unordered_map<std::string,method> method_map; 00009 typedef std::map<int32_t,pending_result::ptr> pending_map; 00010 00016 class connection_base { 00017 public: 00018 typedef boost::shared_ptr<connection_base> ptr; 00019 method_map methods; 00020 pending_map results; 00021 int32_t next_method_id; 00022 int32_t next_req_id; 00023 00024 connection_base():next_method_id(0),next_req_id(0){} 00025 virtual ~connection_base(){} 00026 00027 virtual void close() {} 00028 virtual void send( message&& m ) = 0; 00029 virtual void handle_error( message::error_type, const std::string& message ) = 0; 00030 00031 void break_promises() { 00032 auto itr = results.begin(); 00033 while( itr != results.end() ) { 00034 itr->second->handle_error( message::broken_promise, datavec() ); 00035 ++itr; 00036 } 00037 results.clear(); 00038 } 00039 00044 void handle( message&& m ) { 00045 if( m.meth.size() ) { 00046 auto itr = methods.find( m.meth ); 00047 if( itr != methods.end() ) { 00048 send( itr->second( m ) ); 00049 } else { 00050 handle_error( message::unknown_method, m.meth ); 00051 } 00052 } else if( m.id ) { 00053 auto itr = results.find( *m.id ); 00054 if( itr != results.end() ) { 00055 if( !m.err ) { 00056 itr->second->handle_value( std::move( m.data ) ); 00057 } else { 00058 itr->second->handle_error( m.err, std::move(m.data) ); 00059 } 00060 results.erase(itr); 00061 } else { 00062 handle_error( message::invalid_response, "Unexpected response id "+ boost::lexical_cast<std::string>(*m.id) ); 00063 } 00064 } else { 00065 handle_error( message::invalid_response, "no method or request id" ); 00066 } 00067 } 00068 }; 00069 00070 } } } 00071 00072 #endif // _MACE_RPC_DETAIL_CONNECTION_BASE_HPP_