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/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: "<defer_http_response();
            //触发该方法的执行
            handler_itr->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 );
          }
}

你可能感兴趣的:(Eos源码阅读(nodeos注册cleos的网络请求处理方法))