意见箱
恒创运营部门将仔细参阅您的意见和建议,必要时将通过预留邮箱与您保持联络。感谢您的支持!
意见/建议
提交建议

如何通过EOS代码进行命令注册和通信机制分析

来源:恒创科技 编辑:恒创科技编辑部
2023-12-02 19:58:59

                               

这期内容当中小编将会给大家带来有关如何通过EOS代码进行命令注册和通信机制分析,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

客户端是cleos,服务器端是nodeos,通过cleos命令行控制和管理整个EOS链,非常重要的机制。
客户端和服务器端的通信采用RESTful软件架构风格,服务器端的每个资源对应一个唯一的URL地址,客户端将URL地址封装成http请求发送到服务器端,请求对应的资源或者执行相应操作。

客户端发送消息流程
以转账为例,说明EOS消息处理流程。通过cleos客户端发起转账命令,在main函数中,解析transfer命令,通过create_transfer函数将交易发送者、交易接收者、token数量等信息封装成mutable_variant_object对象,然后调用send_action函数,将交易信息发送到服务器端打包进区块链。


如何通过EOS代码进行命令注册和通信机制分析

./cleos transfer sender recipient amount memo

programs/cleos/main.cpp
main()
{

send_actions({create_transfer(sender, recipient, amount, memo)});

}
void send_actions {
        auto result = push_actions( move(actions), extra_kcpu, compression);
        …
}
fc::variant push_actions {
       signed_transaction trx;
trx.actions = std::forward<decltype(actions)>(actions);
return push_transaction(trx, extra_kcpu, compression);
}
fc::variant push_transaction{
    trx.set_reference_block(ref_block_id);
// 发送 ”/V1/chain/push_transaction” URL地址到服务器端
    if (!tx_dont_broadcast) {
         return call(push_txn_func, packed_transaction(trx, compression));
     }
}
fc::variant call{
       try {
              return eosio::client::http::do_http_call( url, path, fc::variant(v) );
        }
}
fc::variant do_http_call {
       // 将请求的URL封装成http包
       request_stream << “POST ” << path_prefix + path << ” HTTP/1.0”;
request_stream << “Host: ” << server << “”;
request_stream << “content-length: ” << postjson.size() << “”;
request_stream << “Accept: /”;
request_stream << “Connection: close”;
request_stream << postjson;
       // 和服务器建立连接
       do_connect(socket, server, port);
       // 发送http报文,并获取返回结果
       re = do_txrx(socket, request, status_code);
}

服务器接收消息流程
nodeos服务器先通过http_plugin插件接收客户端发过来的http请求报文,然后解析出请求的URL地址和数据信息,然后调用对应的回调函数处理,并将结果返回给cleos客户端。
HTTP消息处理流程
在nodeos的main函数中启动http_plugin插件,注册处理http请求的回调函数(handle_http_request),然后监听socket通信端口,等待建立客户端远程连接。
void http_plugin::plugin_startup() {
      // 注册http请求处理函数
       my->create_server_for_endpoint(my->https_listen_endpoint, my->https_server);
// 监听socket通信端口
my->https_server.listen(
my->https_listen_endpoint);
// 等待建立客户端远程连接
my->https_server.start_accept();  
transport_type::async_accept(&type::handle_accept
// This method will have no effect until the underlying io_service * starts running. It may be called after the io_service is already running.
}
void create_server_for_endpoint{
       ws.set_http_handler([&](connection_hdl hdl) {
handle_http_request<T>(ws.get_con_from_hdl(hdl));
       });
}
         http请求处理函数从http报文中解析出URL地址(resource)、消息内容(body),然后在url_handlers集合中查找URL对应的回调函数,最后通过handler_itr->second调用处理函数。
void handle_http_request {
       …
       auto body = con->get_request_body();
auto resource = con->get_uri()->get_resource();
auto handler_itr = url_handlers.find(resource);
if(handler_itr != url_handlers.end()) {
              handler_itr->second(resource, body, [con](int code, string body) {
                     con->set_body(body);
con->set_status(websocketpp::http::status_code::value(code));
});
       }
       …
}
注册URL处理函数
url_handlers是一个URL和处理函数的键值对map集合,由class http_plugin_impl管理,其它插件模块通过add_api函数注册URL回调函数。
plugins/http_plugin/http_plugin.cpp
class http_plugin_impl {
       map<string,url_handler>  url_handlers;

}
void add_api(const api_description& api) {
       for (const auto& call : api)
add_handler(call.first, call.second);
}
void http_plugin::add_handler {
       …
       my->url_handlers.insert(std::make_pair(url,handler);
}
例如,chain_api_plugin插件在启动函数中注册了以下URL回调函数,包括查询区块信息、处理交易数据:
void chain_api_plugin::plugin_startup() {
       app().get_plugin<http_plugin>().add_api({
CHAIN_RO_CALL(get_info, 200),
CHAIN_RO_CALL(get_block, 200),
              …
     CHAIN_RW_CALL(push_transaction, 202),
CHAIN_RW_CALL(push_transactions, 202)
});
}

上述就是小编为大家分享的如何通过EOS代码进行命令注册和通信机制分析了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注恒创行业资讯频道。

上一篇: mysql直接拷贝data目录下数据库源文件还原数据库方法 下一篇: 怎样用常规密码学解加密python脚本