Eos源码阅读(nodeos注册cleos的网络请求处理方法)

1.nodeos起来的时候main函数会执行各个plugin的startup方法 eos/programs/nodeos/main.cpp

int main(int argc, char** argv){ app().startup(); }

eos/libraries/appbase/application.cpp
void application::startup() { for( auto plugin : initialized_plugins ) { if( is_quiting() ) return; plugin->startup(); //实际调用每个plugin的plugin_startup函数 } }

2. chain_api_plugin的plugin_startup方法 eos/plugins/chain_api_plugin/chain_api_plugin.cpp
void chain_api_plugin::plugin_startup() { //初始化ro_api (chain_plugin) auto ro_api = app().get_plugin().get_read_only_api(); //初始化rw_api (chain_plugin) auto rw_api = app().get_plugin().get_read_write_api(); //注册url与相应处理方法的 _http_plugin.add_api({ CHAIN_RW_CALL_ASYNC(push_transaction, chain_apis::read_write::push_transaction_results, 202), }); }

3. add_api 函数 eos/plugins/http_plugin/include/eosio/http_plugin/http_plugin.hpp
//注册url和对应的handler 方法
void add_api(const api_description& api) { for (const auto& call : api) add_handler(call.first, call.second); }

4. add_handler函数 将url与处理方法的对应关系存入url_handlers(map) eos/plugins/http_plugin/http_plugin.cpp
void http_plugin::add_handler(const string& url, const url_handler& handler) { ilog( "add api url: ${c}", ("c",url) ); app().get_io_service().post([=](){ my->url_handlers.insert(std::make_pair(url,handler)); //注册url对应的处理方法 }); }

5. push_transaction的处理方法 CHAIN_RW_CALL_ASYNC
eos/plugins/chain_api_plugin/chain_api_plugin.cpp
rw_api:在chain_api_plugin的plugin_startup函数中被初始化
#define CHAIN_RW_CALL_ASYNC(call_name, call_result, http_response_code) CALL_ASYNC(chain, rw_api, chain_apis::read_write, call_name, call_result, http_response_code)

最终会调用api_handle(也就是rw_api) 的 call_name(传过来的方法名)。
例如:如果cleos发起的请求是 “v1/chain/push_transaction”,
那么call_name就是"push_transaction",这样最终调用push_transaction方法(实现在eos/plugins/chain_plugin/chain_plugin.cpp)
api_handle.call_name(fc::json::from_string(body).as(),\

6.收到cleos的网络请求后的处理步骤 上面我们讲到了plugin起来时,会将url与对应的处理方法注册在一个map (url_handlers)。 收到请求后,会从url获得resource,然后在url_handlers里查询对应的处理方法,触发它。 【Eos源码阅读(nodeos注册cleos的网络请求处理方法)】eos/plugins/http_plugin/http_plugin.cpp
template void handle_http_request(typename websocketpp::server::connection_ptr con) { auto resource = con->get_uri()->get_resource(); std::cout<<"test http_plugin.cpp handle_http_request resource: "<second( resource, body, [con]( auto code, auto&& body ) { con->set_body( std::move( body )); con->set_status( websocketpp::http::status_code::value( code )); con->send_http_response(); } ); } else { dlog( "404 - not found: ${ep}", ("ep", resource)); error_results results{websocketpp::http::status_code::not_found, "Not Found", error_results::error_info(fc::exception( FC_LOG_MESSAGE( error, "Unknown Endpoint" )), verbose_http_errors )}; con->set_body( fc::json::to_string( results )); con->set_status( websocketpp::http::status_code::not_found ); } }

    推荐阅读