宣èšåJSONã·ãªã¢ã©ã€ã¶ãŒã«é¢ãã以åã®èšäºã§ãC ++ãã³ãã¬ãŒãã䜿çšããŠããŒã¿æ§é ãèšè¿°ããããããã·ãªã¢ã«åããæ¹æ³ã«ã€ããŠèª¬æããŸããã ããã¯éåžžã«äŸ¿å©ã§ã ã³ãŒãã®ãµã€ãºãå°ããããã ãã§ãªããçºçããå¯èœæ§ã®ãããšã©ãŒã®æ°ãæå°éã«æããŸãã ã»ãŒåãã¢ãããŒããwjrpcã«é©çšãããŸãããããã«ã€ããŠã¯ããã®èšäºã§èª¬æããŸãã ããããwjrpcã¯ã€ã³ã¿ãŒãã§ã€ã¹çšã«éçºããããã¬ãŒã ã¯ãŒã¯ãããåŒãè£ãããããããã¢ãŒããã¯ãã£ãšéåæã€ã³ã¿ãŒãã§ã€ã¹ã®åé¡ã«ãè§ŠããŸãã
wjrpcãå®è¡ãããã¡ãã»ãŒãžããŒã¿æ§é ã®JSONèšè¿°ãå®è£
ãããJSONã·ãªã¢ã©ã€ã¶ãŒã«ã€ããŠã¯èª¬æããŸããã åã®èšäºã§wjsonã«ã€ããŠè©±ããŸããã JSON-RPCã®APIãµãŒãã¹ã®èª¬æã®å®£èšããŒãžã§ã³ãæ€èšããåã«ããæåãã§è§£æãå®è£
ããæ¹æ³ãæ€èšããŸãã ããã«ã¯ãããŒã¿ãååŸããŠæ€èšŒããããã«ããå€ãã®ã©ã³ã¿ã€ã ã³ãŒããèšè¿°ããå¿
èŠããããŸãããçè§£ããæ¹ãç°¡åã§ãã ãã¹ãŠã®ãµã³ãã«ã¯ããããžã§ã¯ãã®ãµã³ãã«ã»ã¯ã·ã§ã³ã«ãããŸãã
äŸãšããŠãå ç®ãæžç®ãä¹ç®ãããã³é€ç®æŒç®ãå®è¡ã§ããåçŽãªèšç®æ©ã®APIãæ€èšããŠãã ããã ã¯ãšãªèªäœã¯ç°¡åãªã®ã§ãè¿œå æäœã®ã³ãŒãã®ã¿ãæäŸããŸãã
calc / api / plus.hpp#pragma once #include <memory> #include <functional> namespace request { struct plus { int first=0; int second=0; typedef std::unique_ptr<plus> ptr; }; } // request namespace response { struct plus { int value=0; typedef std::unique_ptr<plus> ptr; typedef std::function<void(ptr)> callback; }; } // response
ãã®ç®çã®ããã«æå®ããããã©ã«ããŒå
ã®åå¥ã®ãã¡ã€ã«ã«ãåèŠæ±/å¿çãã¢ã®æ§é ãé
眮ããããšã奜ã¿ãŸãã ããã«ããããããžã§ã¯ãå
ãç°¡åã«ç§»åã§ããŸãã äžèšã®äŸã«ç€ºãããã«ãããŒã ã¹ããŒã¹ã䜿çšããŠãã«ããŒã¿ã€ããå®çŸ©ããå¿
èŠã¯ãããŸããããã³ãŒãã®å¯èªæ§ã¯åäžããŸãã ãããã®typedefã®æå³ã«ã€ããŠã¯ãåŸã§èª¬æããŸãã
èŠæ±ããšã«ãJSONèšè¿°ãäœæããŸãã
calc / api / plus_json.hpp #pragma once #include "calc/api/plus.hpp" #include <wjson/json.hpp> #include <wjson/name.hpp> namespace request { struct plus_json { JSON_NAME(first) JSON_NAME(second) typedef wjson::object< plus, wjson::member_list< wjson::member<n_first, plus, int, &plus::first>, wjson::member<n_second, plus, int, &plus::second> > > type; typedef typename type::serializer serializer; typedef typename type::target target; }; } namespace response { struct plus_json { JSON_NAME(value) typedef wjson::object< plus, wjson::member_list< wjson::member<n_value, plus, int, &plus::value> > > type; typedef typename type::serializer serializer; typedef typename type::target target; }; }
ãããæ§é ã«å
¥ããçç±ã¯ãwjsonã®èšäºã§èª¬æããŸããã ããã§ã¯ããããã®æ§é ãJSONèšè¿°ãšããŠèªèãããããã«typedefã®å®çŸ©ãå¿
èŠã§ããããšã«æ³šæããŠãã ããã
JSON-RPCã¡ãã»ãŒãžã®åŠçã¯ã2ã€ã®æ®µéã«åããããšãã§ããŸãã æåã®æ®µéã§ããªã¯ãšã¹ãã®ã¿ã€ããšã¡ãœããã®ååãæ±ºå®ãã2çªç®ã«ããã®ã¡ãœããã®ãã©ã¡ãŒã¿ãŒããã·ãªã¢ã©ã€ãºããå¿
èŠããããŸãã
plusçšã®ã·ãªã¢ã«åãããJSON-RPC <p>{ "jsonrpc":"2.0", "method":"plus", "params":{ "first":2, "second":3 }, "id":1 }</p> <source> , : ```cpp struct request { std::string version, std::string method, std::string params, std::string id }
ãªã¯ãšã¹ãã®JSONã®èª¬æ JSON_NAME(jsonrpc) JSON_NAME(method) JSON_NAME(params) JSON_NAME(id) typedef wjson::object< request, wjson::member_list< wjson::member<n_jsonrpc, request, std::string, &request::version>, wjson::member<n_method, request, std::string, &request::method>, wjson::member<n_params, request, std::string, &request::params, json::raw_value<> >, wjson::member<n_id, request, std::string, &request::id, json::raw_value<> > > > request_json;
ãã®èª¬æã§ã¯ã request::params
ããã³request::id
ãã£ãŒã«ãã«jsonã倿ãããã«ãã®ãŸãŸã³ããŒããã request::method
ãã£ãŒã«ãã«å®éã®ã¡ãœããåããããŸãã ã¡ãœããã®ååãå®çŸ©ããããäžèšã®æ§é ã䜿çšããŠãã©ã¡ãŒã¿ãŒãéã·ãªã¢ã«åã§ããŸãã
ã¡ãœããåãæ±ºå®ããããã«ãã¯ãšãªå
šäœãäžéããŒã¿æ§é ã«éã·ãªã¢ã«åããå¿
èŠã¯ãããŸããã ãããè§£æããparamsãã£ãŒã«ãã«é¢é£ãããªã¯ãšã¹ãã®äžéšã®ã¿ããã·ãªã¢ã©ã€ãºããã°ååã§ãã ããã¯wjson ::ããŒãµãŒãçŽæ¥äœ¿çšããŠè¡ãããšãã§ããŸãããwjsonã¯raw_pairã³ã³ã¹ãã©ã¯ããæäŸããŸãïŒä»¥åã®èšäºã§ã¯èæ
®ããŸããã§ããïŒã ãããwjrpcã§ã©ã®ããã«å®è£
ãããŠããããèŠãŠã¿ãŸãããã
ãŸããwjrpcã¯std :: stringæååã§ã¯æ©èœããŸããããæ¬¡ã®ã¿ã€ããå®çŸ©ããŸãã
namespace wjrpc { typedef std::vector<char> data_type; typedef std::unique_ptr<data_type> data_ptr; }
data_ptrãç§»åå¯èœãªãããã¡ãŒãšèŠãªãããšãã§ããŸããããã䜿çšããããšã§ãããŒã¿ã誀ã£ãŠå床ã³ããŒãããªãããšãä¿èšŒã§ããŸãã
çä¿¡ããwjrpcã¡ãã»ãŒãžã¯ãæ¬¡ã®æ§é ã«ãã·ãªã¢ã©ã€ãºããããšããŸãã
wjrpc ::çä¿¡ namespace wjrpc { struct incoming { typedef data_type::iterator iterator; typedef std::pair<iterator, iterator> pair_type; pair_type method; pair_type params; pair_type result; pair_type error; pair_type id; }; }
ãã¹ãŠã®wjrpc ::çä¿¡èŠçŽ ã¯ãå
¥åãããã¡å
ã®ã€ãã¬ãŒã¿ã®ãã¢ã§ãã ããšãã°ãéã·ãªã¢ã«åäžã«ãmethod.firstã¯å
¥åèŠæ±ã®ã³ãã³ã®åŸã«ã¡ãœããåãéãåŒçšç¬Šãæããmethod.secondã¯éãåŒçšç¬Šã®æ¬¡ã®äœçœ®ãæããŸãã ãã®æ§é ã¯ãèŠæ±ã ãã§ãªããèŠæ±ãžã®å¿çãããã³ãšã©ãŒã¡ãã»ãŒãžãèšè¿°ããŸãã ãã£ãŒã«ãã«å
¥åããããšã«ãããã¡ãã»ãŒãžã®ã¿ã€ããå€å¥ããã®ã¯éåžžã«ç°¡åã§ãã ãã®ãããªæ§é ã®JSONèšè¿°ïŒ
wjrpc :: incoming_json namespace wjrpc { struct incoming_json { typedef incoming::pair_type pair_type; typedef wjson::iterator_pair<pair_type> pair_json; JSON_NAME(id) JSON_NAME(method) JSON_NAME(params) JSON_NAME(result) JSON_NAME(error) typedef wjson::object< incoming, wjson::member_list< wjson::member<n_method, incoming, pair_type, &incoming::method, pair_json>, wjson::member<n_params, incoming, pair_type, &incoming::params, pair_json>, wjson::member<n_result, incoming, pair_type, &incoming::result, pair_json>, wjson::member<n_error, incoming, pair_type, &incoming::error, pair_json>, wjson::member<n_id, incoming, pair_type, &incoming::id, pair_json> > > type; typedef type::target target; typedef type::member_list member_list; typedef type::serializer serializer; }; }
æ¬æ Œçãªãã·ãªã¢ã©ã€ãŒãŒã·ã§ã³ã¯ãããŸãã-ããã¯ãå
¥åãããã¡ã«äœçœ®ãä¿åããããšã§æ¬è³ªçã«è§£æãããŸãã æããã«ããã®ãããªéã·ãªã¢ã«åã®åŸãããŒã¿ã¯å
¥åãããã¡ãååšããéã®ã¿æå¹ã«ãªããŸãã
wjrpc :: incoming_holderã¯ã©ã¹ã¯ããªã¯ãšã¹ããããã¡ããã£ããã£ããäžèšã®æ§é ã«è§£æããŸãã ã€ã³ã¿ãŒãã§ãŒã¹ã®è©³çްã¯èª¬æããŸããããJSON-RPCã®å®è£
ã«äœ¿çšããæ¹æ³ã瀺ããŸãã
æåã«åçŽåããã1ã€ã®ã¡ãœããã®äŸ #include "calc/api/plus.hpp" #include "calc/api/plus_json.hpp" #include <wjrpc/errors/error_json.hpp> #include <wjrpc/incoming/incoming_holder.hpp> #include <wjrpc/outgoing/outgoing_holder.hpp> #include <wjrpc/outgoing/outgoing_result.hpp> #include <wjrpc/outgoing/outgoing_result_json.hpp> #include <wjrpc/outgoing/outgoing_error.hpp> #include <wjrpc/outgoing/outgoing_error_json.hpp> #include <iostream> int main() { std::vector<std::string> req_list = { "{\"method\":\"plus\", \"params\":{ \"first\":2, \"second\":3 }, \"id\" :1 }", "{\"method\":\"minus\", \"params\":{ \"first\":5, \"second\":10 }, \"id\" :1 }", "{\"method\":\"multiplies\", \"params\":{ \"first\":2, \"second\":2 }, \"id\" :1 }", "{\"method\":\"divides\", \"params\":{ \"first\":9, \"second\":3 }, \"id\" :1 }" }; std::vector<std::string> res_list; for ( auto& sreq : req_list ) { wjrpc::incoming_holder inholder( sreq ); // inholder.parse(nullptr); // if ( inholder.method() == "plus" ) { // auto params = inholder.get_params<request::plus_json>(nullptr); // wjrpc::outgoing_result<response::plus> res; res.result = std::make_unique<response::plus>(); // res.result->value = params->first + params->second; // id auto raw_id = inholder.raw_id(); res.id = std::make_unique<wjrpc::data_type>( raw_id.first, raw_id.second ); // typedef wjrpc::outgoing_result_json<response::plus_json> result_json; res_list.push_back(std::string()); result_json::serializer()( res, std::back_inserter(res_list.back()) ); } /* else if ( inholder.method() == "minus" ) { ... } */ /* else if ( inholder.method() == "multiplies" ) { ... } */ /* else if ( inholder.method() == "divides" ) { ... } */ } for ( size_t i =0; i != res_list.size(); ++i) { std::cout << req_list[i] << std::endl; std::cout << res_list[i] << std::endl; std::cout << std::endl; } }
ããã§ã¯ããšã©ãŒã®ãã§ãã¯ãè¡ã£ãŠããªããããã»ãšãã©ã®ã³ãŒããåçã®åœ¢æã«å æãããŠããŸãã ãŸããincoming_holderãæååã§åæåããŠè§£æããŸãã ãã®æç¹ã§ãå
¥åæååã¯äžèšã®çä¿¡æ§é ã«éã·ãªã¢ã«åãããŸãã æååã«æå¹ãªjsonãªããžã§ã¯ããå«ãŸããŠããå Žåããã®ã¹ãããã¯ãšã©ãŒãªãã§åæ ŒããŸãã
次ã«ããªã¯ãšã¹ãã®ã¿ã€ããæ±ºå®ããå¿
èŠããããŸãã ããã¯ããmethodãããresultãããerrorããããã³ãidããã£ãŒã«ãã®æç¡ã«ãã£ãŠç°¡åã«å®è¡ã§ããŸãã
çµã¿åãã | ã¡ãã»ãŒãžã®çš®é¡ | 確èªãã | ååŸãã |
---|
ã¡ãœãããšID | ãªã¯ãšã¹ã | is_request | get_params <> |
IDã®ãªãã¡ãœãã | æ°ã¥ã | is_notify | get_params <> |
çµæãšID | ãªã¯ãšã¹ããžã®å¿ç | is_response | get_result <> |
ãšã©ãŒãšID | ãªã¯ãšã¹ããžã®å¿çãšã©ãŒ | is_request_error | get_error <> |
IDãªãã®ãšã©ãŒ | ãã®ä»ã®ãšã©ãŒ | is_other_error | get_error <> |
ãããã®æ¡ä»¶ãæºããããªãå Žåããªã¯ãšã¹ããæ£ãããªãããšã¯æããã§ãã
ãã§ãã¯ãš1ã€ã®ã¡ãœããã®äŸ #include "calc/api/plus.hpp" #include "calc/api/plus_json.hpp" #include <wjrpc/errors/error_json.hpp> #include <wjrpc/incoming/incoming_holder.hpp> #include <wjrpc/outgoing/outgoing_holder.hpp> #include <wjrpc/outgoing/outgoing_result.hpp> #include <wjrpc/outgoing/outgoing_result_json.hpp> #include <wjrpc/outgoing/outgoing_error.hpp> #include <wjrpc/outgoing/outgoing_error_json.hpp> #include <iostream> int main() { std::vector<std::string> req_list = { "{\"method\":\"plus\", \"params\":{ \"first\":2, \"second\":3 }, \"id\" :1 }", "{\"method\":\"minus\", \"params\":{ \"first\":5, \"second\":10 }, \"id\" :1 }", "{\"method\":\"multiplies\", \"params\":{ \"first\":2, \"second\":2 }, \"id\" :1 }", "{\"method\":\"divides\", \"params\":{ \"first\":9, \"second\":3 }, \"id\" :1 }" }; std::vector<std::string> res_list; for ( auto& sreq : req_list ) { wjrpc::incoming_holder inholder( sreq ); wjson::json_error e; inholder.parse(&e); if ( e ) { typedef wjrpc::outgoing_error<wjrpc::error> error_type; error_type err; err.error = std::make_unique<wjrpc::parse_error>(); typedef wjrpc::outgoing_error_json<wjrpc::error_json> error_json; std::string str; error_json::serializer()(err, std::back_inserter(str)); res_list.push_back(str); } else if ( inholder.is_request() ) { auto raw_id = inholder.raw_id(); auto call_id = std::make_unique<wjrpc::data_type>( raw_id.first, raw_id.second ); // if ( inholder.method() == "plus" ) { auto params = inholder.get_params<request::plus_json>(&e); if ( !e ) { wjrpc::outgoing_result<response::plus> res; res.result = std::make_unique<response::plus>(); res.result->value = params->first + params->second; res.id = std::move(call_id); typedef wjrpc::outgoing_result_json<response::plus_json> result_json; std::string str; result_json::serializer()( res, std::back_inserter(str) ); res_list.push_back(str); } else { typedef wjrpc::outgoing_error<wjrpc::error> error_type; error_type err; err.error = std::make_unique<wjrpc::invalid_params>(); err.id = std::move(call_id); typedef wjrpc::outgoing_error_json<wjrpc::error_json> error_json; std::string str; error_json::serializer()(err, std::back_inserter(str)); res_list.push_back(str); } } /* else if ( inholder.method() == "minus" ) { ... } */ /* else if ( inholder.method() == "multiplies" ) { ... } */ /* else if ( inholder.method() == "divides" ) { ... } */ else { typedef wjrpc::outgoing_error<wjrpc::error> error_type; error_type err; err.error = std::make_unique<wjrpc::procedure_not_found>(); err.id = std::move(call_id); typedef wjrpc::outgoing_error_json<wjrpc::error_json> error_json; std::string str; error_json::serializer()(err, std::back_inserter(str)); res_list.push_back(str); } } else { typedef wjrpc::outgoing_error<wjrpc::error> error_type; error_type err; err.error = std::make_unique<wjrpc::invalid_request>(); typedef wjrpc::outgoing_error_json<wjrpc::error_json> error_json; std::string str; error_json::serializer()(err, std::back_inserter(str)); res_list.push_back(str); } } for ( size_t i =0; i != res_list.size(); ++i) { std::cout << req_list[i] << std::endl; std::cout << res_list[i] << std::endl; std::cout << std::endl; } }
ããã§ãã»ãšãã©ã®ã³ãŒãã¯ãšã©ãŒåŠçããŸãã¯å¯Ÿå¿ããã¡ãã»ãŒãžã®åœ¢æã§ãã ãããããã¹ãŠã®ã¿ã€ãã®ãšã©ãŒã«ã€ããŠã¯ã³ãŒãã¯äŒŒãŠãããéãã¯ãšã©ãŒã®ã¿ã€ãã®ã¿ã§ãã 1ã€ã®å®å颿°ãäœæããŠããã¹ãŠã®ã¿ã€ãã®ãšã©ãŒãã·ãªã¢ã«åã§ããŸãã
ãšã©ãŒå ±å template<typename E> void make_error(wjrpc::incoming_holder inholder, std::string& out) { typedef wjrpc::outgoing_error<wjrpc::error> common_error; common_error err; err.error = std::make_unique<E>(); if ( inholder.has_id() ) { auto id = inholder.raw_id(); err.id = std::make_unique<wjrpc::data_type>(id.first, id.second); } typedef wjrpc::outgoing_error_json<wjrpc::error_json> error_json; error_json::serializer()(err, std::back_inserter(out)); }
ãšã©ãŒã¡ãã»ãŒãžãçæããã«ã¯ããšã©ãŒã®çš®é¡ãšåŒã³åºãèå¥åïŒååšããå ŽåïŒãç¥ãã ãã§ãã ã€ã³ãã«ããŒãªããžã§ã¯ãã¯åé
眮å¯èœã§ãããã¡ãã»ãŒãžã®åœ¢æåŸã¯äžèŠã«ãªããŸãã ãã®äŸã§ã¯ãåŒã³åºãèå¥åãååŸããããã«ã®ã¿äœ¿çšãããŸãããããããå
¥åãããã¡ããããã¯ã¢ãããããŠãããã«ã¡ãã»ãŒãžãã·ãªã¢ã«åããŠãæ°ãããããã¡ãäœæããªãããã«ããããšãã§ããŸãã
åæ§ã«ãçµæã®ã·ãªã¢ã«åãå®è£
ã§ããŸãã ããããåãã¿ã€ãã®ã³ãŒããåãé€ãç¶ããåã«ãã¢ããªã±ãŒã·ã§ã³éšåãæŽçããŸããã¢ããªã±ãŒã·ã§ã³éšåã¯ããã§ã¯å€å°å€±ãããåã¡ãœããã«å¯ŸããŠ1è¡ã ãã§è¡šãããŸãã
ã€ã³ã¿ãŒãã§ãŒã¹
åè¿°ããããã«ãwjrpcã¯ãã³ã³ããŒãã³ãã®ã€ã³ã¿ãŒãã§ã€ã¹ãæç€ºçã«å®çŸ©ããå¿
èŠããããã¬ãŒã ã¯ãŒã¯ããåŒãè£ãããŠããŸãã ããã«ãããã¯çŽç²ãªä»®æ³ã¡ãœããã ãã®æ§é ã§ã¯ãªããã¡ãœããã®ãã©ã¡ãŒã¿ãŒã«ç¹å®ã®å¶éã課ããããŸãã
ãã£ãŒã«ãã1ã€ãããªãå Žåã§ãããã¹ãŠã®å
¥åããã³åºåãã©ã¡ãŒã¿ãŒãçµåããŠæ§é äœã«ããå¿
èŠããããŸãã ããã¯ããªã¯ãšã¹ãã®JSONèšè¿°ãçæããã®ã«äŸ¿å©ã§ããäºåã«å€æããã«ããã·ãªã¢ã©ã€ãºãããæ§é ãã¡ãœããã«çŽæ¥æž¡ãããšãã§ããå Žåã ãã§ãªããæ¡åŒµæ§ã®ç¹ããã䟿å©ã§ãã
ããšãã°ããã¹ãŠã®ã¡ãœããã§ãæ°å€-æäœã®çµæãè¿ããŸãã å¯èœã§ããã°æ°åã§1ã€ã®ãã£ãŒã«ããæã€æ§é äœã§çµæã説æããæå³ã¯ãããŸããïŒ ãŸããäžè¬çã«å
¥åãã©ã¡ãŒã¿ãŒã¯é
åïŒäœçœ®ãã©ã¡ãŒã¿ãŒïŒã§æž¡ãããšãã§ããŸãã
ãã ããèŠä»¶ãå°ã倿Žãããä»éããæ
å ±ããã©ã¡ãŒã¿ãŒã®ãªã¹ãã«è¿œå ããå¿
èŠããããããŸãã¯é€ç®æäœã®å Žåã¯ãŒãã«ããé€ç®ãçºçããããšãæå³ãããã©ã°ã远å ããå¿
èŠããããšããŸãã ãã®å Žåãä¿®æ£ããã«ã¯ãã€ã³ã¿ãŒãã§ã€ã¹ãšãã®ãã¹ãŠã®å®è£
ã ãã§ãªãã䜿çšãããŠãããã¹ãŠã®å Žæããã·ã§ã€ã¯ã¢ãããããå¿
èŠããããŸãã
JSON-RPCãµãŒãã¹ãããå Žåã倿Žã¯ãµãŒããŒã ãã§ãªãã¯ã©ã€ã¢ã³ãã«ã圱é¿ããŸããã¯ã©ã€ã¢ã³ãã®ã€ã³ã¿ãŒãã§ãŒã¹ã¯äœããã®åœ¢ã§èª¿æŽããå¿
èŠããããŸãã ãŸããæ§é ã®å Žåã¯ãæ§é ã«ãã£ãŒã«ãã远å ããã ãã§ãã ããã«ãã¯ã©ã€ã¢ã³ãéšåãšãµãŒããŒéšåã¯åå¥ã«æŽæ°ã§ããŸãã
ãã¬ãŒã ã¯ãŒã¯ã®ãã1ã€ã®ç¹åŸŽã¯ããã¹ãŠã®ã¡ãœããã«éåæã€ã³ã¿ãŒãã§ã€ã¹ãããããšã§ãã çµæã¯çŽæ¥ã§ã¯ãªããã³ãŒã«ããã¯é¢æ°ãéããŠè¿ãããŸãã ãŸããäžæ³šæã«ããã³ããŒãšã©ãŒãé¿ãããããå
¥åããã³åºåãªããžã§ã¯ãã¯std :: unique_ptr <>ãšããŠèšè¿°ãããŸãã
èšç®æ©ã§ã¯ã説æãããŠããå¶éãèæ
®ããŠã次ã®ã€ã³ã¿ãŒãã§ã€ã¹ãååŸããŸãã
struct icalc { virtual ~icalc() {} virtual void plus( request::plus::ptr req, response::plus::callback cb) = 0; virtual void minus( request::minus::ptr req, response::minus::callback cb) = 0; virtual void multiplies( request::multiplies::ptr req, response::multiplies::callback cb) = 0; virtual void divides( request::divides::ptr req, response::divides::callback cb) = 0; };
å
¥åæ§é ã§å®çŸ©ããè£å©typedefãèãããšãããªãèŠæ ããããŸãã ãããããã®ãããªã€ã³ã¿ãŒãã§ãŒã¹ã®å®è£
ã¯ãæ¯èŒçåçŽãªäŸã§ã¯ããªãèšå€§ã«ãªãå¯èœæ§ããããŸãã å
¥åèŠæ±ãnullptrã§ãªãããšã確èªããã³ãŒã«ããã¯é¢æ°ã確èªããå¿
èŠããããŸãã å®çŸ©ãããŠããªãå Žåãããã¯éç¥ã§ããããšãæããã§ããããã®å ŽåãåŒã³åºãã¯ç¡èŠããå¿
èŠããããŸãã èšç®æ©ã®å®è£
äŸã«ç€ºãããã«ããã®æ©èœã¯ãã³ãã¬ãŒãåãç°¡åã§ãã
calc1.hpp #pragma once #include "icalc.hpp" class calc1 : public icalc { public: virtual void plus( request::plus::ptr req, response::plus::callback cb) override; virtual void minus( request::minus::ptr req, response::minus::callback cb) override; virtual void multiplies( request::multiplies::ptr req, response::multiplies::callback cb) override; virtual void divides( request::divides::ptr req, response::divides::callback cb) override; private: template<typename Res, typename ReqPtr, typename Callback, typename F> void impl_( ReqPtr req, Callback cb, F f); };
calc1.cpp #include "calc1.hpp" #include <wjrpc/memory.hpp> template<typename Res, typename ReqPtr, typename Callback, typename F> void calc1::impl_( ReqPtr req, Callback cb, F f) { // if ( cb == nullptr ) return; // if ( req == nullptr ) return cb(nullptr); auto res = std::make_unique<Res>(); res->value = f(req->first,req->second); cb( std::move(res) ); } void calc1::plus( request::plus::ptr req, response::plus::callback cb) { this->impl_<response::plus>( std::move(req), cb, [](int f, int s) { return f+s; } ); } void calc1::minus( request::minus::ptr req, response::minus::callback cb) { this->impl_<response::minus>( std::move(req), cb, [](int f, int s) { return fs; }); } void calc1::multiplies( request::multiplies::ptr req, response::multiplies::callback cb) { this->impl_<response::multiplies>( std::move(req), cb, [](int f, int s) { return f*s; }); } void calc1::divides( request::divides::ptr req, response::divides::callback cb) { this->impl_<response::divides>( std::move(req), cb, [](int f, int s) { return s!=0 ? f/s : 0; }); }
ãã®èšäºã¯ãŸã é»åã®å®è£
ã«é¢ãããã®ã§ã¯ãªããããäžèšã®ã³ãŒãããã¹ããã©ã¯ãã£ã¹ãšèŠãªãã¹ãã§ã¯ãããŸããã ã¡ãœããåŒã³åºãã®äŸïŒ
calc->plus( std::move(params), [](response::plus::ptr result) { ⊠});
ã€ã³ã¿ãŒãã§ã€ã¹ã®ãããã¯ã«æ»ããŸããããµãŒãã¹ã®ã³ãŒããåŒãç¶ããåæžãããŸãã çµæãéåæã«ã·ãªã¢ã«åããã«ã¯ãçä¿¡ãªã¯ãšã¹ããããã£ããã£ãããå¿
èŠããããŸã
äŸãã° std::shared_ptr<wjrpc::incoming_holder> ph = std::make_shared<wjrpc::incoming_holder>( std::move(inholder) ); calc->plus( std::move(params), [ph, &res_list](response::plus::ptr result) {
ãªããªã incoming_holderã¯ç§»åå¯èœã§ãããããããã£ããã£ãããã«ã¯ãstd :: shared_ptrã«ç§»åããŸãã 圌ãããããã¡ãååŸããæ¹æ³ã瀺ããŠããŸããããã®å Žåã¯ããŸãæå³ããããŸãã-ãšã«ãããçµæãè¡ã®ãªã¹ãã«å
¥ããŸãã åç
§ã«ããres_listã®ãã£ããã£ã¯ãåãªãäŸã§ãã èŠæ±ã¯åæçã«å®è¡ãããããšãããã£ãŠããŸãã
ãšã©ãŒãã·ãªã¢ã«åããããã®ãã³ãã¬ãŒã颿°ããã§ã«äœæããŸãããåçã«ã€ããŠãåãããšãè¡ããŸãã ãã ãããã®ããã«ã¯ãçµæã®åã«å ããŠããã®å€ãšJSONã®èª¬æãæž¡ãå¿
èŠããããŸãã
ãŠãããŒãµã«ã¯ãšãªã¬ã¹ãã³ã¹ã·ãªã¢ã©ã€ã¶ãŒ template<typename ResJ> void send_response(std::shared_ptr<wjrpc::incoming_holder> ph, typename ResJ::target::ptr result, std::string& out) { typedef ResJ result_json; typedef typename result_json::target result_type; wjrpc::outgoing_result<result_type> resp; resp.result = std::move(result); auto raw_id = ph->raw_id(); resp.id = std::make_unique<wjrpc::data_type>( raw_id.first, raw_id.second ); typedef wjrpc::outgoing_result_json<result_json> response_json; typename response_json::serializer()( resp, std::back_inserter( out ) ); }
ããã§ã¯ããã³ãã¬ãŒããã©ã¡ãŒã¿ãæç€ºçã«æå®ããå¿
èŠããããŸããããã¯ãå¿çæ§é ã®JSONèšè¿°ã§ãããèšè¿°ãããæ§é ã®ã¿ã€ããååŸã§ããŸãã ãã®é¢æ°ã䜿çšãããšãåJSON-RPCã¡ãœããã®ã³ãŒãã倧å¹
ã«ç°¡çŽ åãããŸãã
plusã¡ãœããã®æ°ããããŒãžã§ã³ if ( inholder.method() == "plus" ) {
åã¡ãœããã«ã€ããŠãã³ãŒãã¯æå°éã«åæžãããŸããããããã§ã¯ååã§ã¯ãããŸããã ãã©ã¡ãŒã¿ã®ååŸãšãšã©ãŒã®ãã§ãã¯ãåãã¿ã€ãã®ã³ãŒãã§ãã
ã·ãªã¢ã«åãšã¡ãœããåŒã³åºã template< typename JParams, typename JResult, void (icalc::*mem_ptr)( std::unique_ptr<typename JParams::target>, std::function< void(std::unique_ptr<typename JResult::target>) > ) > void invoke(wjrpc::incoming_holder inholder, std::shared_ptr<icalc> calc, std::string& out) { typedef JParams params_json; typedef JResult result_json; wjson::json_error e; auto params = inholder.get_params<params_json>(&e); if ( !e ) { std::shared_ptr<wjrpc::incoming_holder> ph = std::make_shared<wjrpc::incoming_holder>( std::move(inholder) ); (calc.get()->*mem_ptr)( std::move(params), std::bind( send_response<result_json>, ph, std::placeholders::_1, std::ref(out) ) ); } else { out = make_error<wjrpc::invalid_params>(); } }
ããã¯wjrpcã§å®è£
ãããŠãããã®ãšã»ãŒåãã§ãã ãã®çµæããã¢äŸã®ã³ãŒãã¯æå°éã«åæžãããŸãïŒããã§ããã¹ãŠã®ã¡ãœããã®å®è£
ãæ¢ã«æäŸã§ããŸãïŒã
ãæååŠçãã䜿çšããäŸã®æçµããŒãžã§ã³ int main() { std::vector<std::string> req_list = { "{\"method\":\"plus\", \"params\":{ \"first\":2, \"second\":3 }, \"id\" :1 }", "{\"method\":\"minus\", \"params\":{ \"first\":5, \"second\":10 }, \"id\" :1 }", "{\"method\":\"multiplies\", \"params\":{ \"first\":2, \"second\":2 }, \"id\" :1 }", "{\"method\":\"divides\", \"params\":{ \"first\":9, \"second\":3 }, \"id\" :1 }" }; std::vector<std::string> res_list; auto calc = std::make_shared<calc1>(); for ( auto& sreq : req_list ) { res_list.push_back( std::string() ); std::string& out = res_list.back(); wjrpc::incoming_holder inholder( sreq ); wjson::json_error e; inholder.parse(&e); if ( e ) { out = make_error<wjrpc::parse_error>(); } else if ( inholder.is_request() ) {
å®è¡æã®ã³ãŒãéãæžãããããšããSuchãªæ¬²æ±ã¯ãããã€ãã®çç±ã«ãããã®ã§ãã ããªãè€éãªãã¶ã€ã³ã䜿çšããŠäžèŠãªif
ãåé€ããããšã§ãã³ãŒãã®éãæžããã ãã§ãªããããã°ã©ããŒãnagovoditã«æºè¶³ããå¯èœæ§ã®ããå Žæãåé€ããŸãã ãŸããã³ããŒããŒã¹ããªã©ã®ããã°ã©ããŒãç¹ã«ã·ãªã¢ã«åã«é¢é£ããé¢çœããªãã³ãŒãããããžã§ã¯ãå
šäœãžã®æ¡æ£ããŸãã¯ä»ã®ãããžã§ã¯ããžã®æã¡èŸŒã¿ãããå¯èœã§ãã æ azineã¯é²æ©ã®ãšã³ãžã³ã§ããã人ã
ãä»äºãæžããããšãå¯èœã«ããäœããçºæããããšãã§ãã ããããç©äºãåŸãŸã§å»¶æãããå Žåã¯ããã§ã¯ãããŸããã äºçްãªãã§ãã¯ã®ããã«æããŸãããèšèã§èšãã°ãããã¯ãŸã ãããã¿ã€ãã§ãããæ°è¡ã®ã³ãŒããæžãã®ã¯å»¶æãããå¿ããããŠåæã«ãããžã§ã¯ãå
šäœã«ã³ããŒãããä»ã®ããã°ã©ããŒã«ãã£ãŠåãäžããããŸãã
å®éãwjrpcã®æ€èšã¯ãŸã å§ãŸã£ãŠããŸãããwjsonã䜿çšããŠãªã¯ãšã¹ããã©ã®ããã«èšè¿°ããããã瀺ãããã¹ãã±ãŒã¹ã®ã€ã³ã¿ãŒãã§ã€ã¹ãšã¢ããªã±ãŒã·ã§ã³ããžãã¯ãèšè¿°ããJSON-RPCãæåã§å®è£
ããæ¹æ³ãæ€èšããŸãããå®å
šãªwjrpcã®äŸã次ã«ç€ºããŸãã
#include "calc/calc1.hpp" #include "calc/api/plus_json.hpp" #include "calc/api/minus_json.hpp" #include "calc/api/multiplies_json.hpp" #include "calc/api/divides_json.hpp" #include <wjrpc/handler.hpp> #include <wjrpc/method.hpp> #include <iostream> #include <functional> JSONRPC_TAG(plus) JSONRPC_TAG(minus) JSONRPC_TAG(multiplies) JSONRPC_TAG(divides) struct method_list: wjrpc::method_list < wjrpc::target<icalc>, wjrpc::invoke_method<_plus_, request::plus_json, response::plus_json, icalc, &icalc::plus>, wjrpc::invoke_method<_minus_, request::minus_json, response::minus_json, icalc, &icalc::minus>, wjrpc::invoke_method<_multiplies_, request::multiplies_json, response::multiplies_json, icalc, &icalc::multiplies>, wjrpc::invoke_method<_divides_, request::divides_json, response::divides_json, icalc, &icalc::divides> >{}; class handler: public wjrpc::handler<method_list> {}; int main() { std::vector<std::string> req_list = { "{\"method\":\"plus\", \"params\":{ \"first\":2, \"second\":3 }, \"id\" :1 }", "{\"method\":\"minus\", \"params\":{ \"first\":5, \"second\":10 }, \"id\" :1 }", "{\"method\":\"multiplies\", \"params\":{ \"first\":2, \"second\":2 }, \"id\" :1 }", "{\"method\":\"divides\", \"params\":{ \"first\":9, \"second\":3 }, \"id\" :1 }" }; std::vector<std::string> res_list; auto calc = std::make_shared<calc1>(); handler h; handler::options_type opt; opt.target = calc; h.start(opt, 1); for ( auto& sreq : req_list ) { h.perform( sreq, [&res_list](std::string out) { res_list.push_back(out);} ); } for ( size_t i =0; i != res_list.size(); ++i) { std::cout << req_list[i] << std::endl; std::cout << res_list[i] << std::endl; std::cout << std::endl; } }
JSONRPC_TAGã䜿çšããŠãwjsonã®JSON NAMEãšåæ§ã«ããã³ãã¬ãŒããã©ã¡ãŒã¿ãŒãšããŠæž¡ãã¡ãœããåãæå®ããŸããå¯äžã®éãã¯ããã¬ãã£ãã¯ã¹nã®ä»£ããã«ã¢ã³ããŒã¹ã³ã¢ã§å²ãŸãããšã³ãã£ãã£ã®ååã§ãã
次ã«ãwjrpc :: method_listããã³wjrpc :: invoke_methodã䜿çšããŠã䜿çšå¯èœãªãã¹ãŠã®ã¡ãœããã«ã€ããŠèª¬æããŸããã¡ãœããã®ãªã¹ãã¯wjrpc ::ãã³ãã©ãŒhandlerã«æž¡ãããŸãããªã¹ãã¯ãã¡ãœãããšãšãã«ããã³ãã©ãŒãåäœãããªããžã§ã¯ãã®ã€ã³ã¿ãŒãã§ã€ã¹ã¿ã€ããèšè¿°ããŸããã
perform_io, wjrpc::data_ptr.
typedef std::vector<char> data_type; typedef std::unique_ptr<data_type> data_ptr; typedef std::function< void(data_ptr) > output_handler_t; void perform_io(data_ptr d, output_handler_t handler) { ⊠} void perform(std::string str, std::function<void(std::string)> handler) { auto d = std::make_unique<data_type>( str.begin(), str.end() ); this->perform_io( std::move(d), [handler](data_ptr d) { handler( std::string(d->begin(), d->end()) ); }); }
, . , , ,
, struct plus_handler { template<typename T> void operator()(T& t, request::plus::ptr req) {
struct plus_handler { template<typename T> void operator()(T&, request::plus::ptr req) { } template<typename T, typename Handler> void operator()(T&, request::plus::ptr req, Handler handler) { if (req==nullptr) { handler( nullptr, std::make_unique<wjrpc::invalid_params>() ); return; } auto res = std::make_unique<response::plus>(); res->value = req->first + req->second; handler( std::move(res), nullptr ); } };
handler , , . t â JSON-RPC- ( self python). :
struct method_list: wjrpc::method_list < wjrpc::target<icalc>, wjrpc::method< wjrpc::name<_plus_>, wjrpc::invoke<request::plus_json, response::plus_json, plus_handler> >, wjrpc::invoke_method<_minus_, request::minus_json, response::minus_json, icalc, &icalc::minus>, wjrpc::invoke_method<_multiplies_, request::multiplies_json, response::multiplies_json, icalc, &icalc::multiplies>, wjrpc::invoke_method<_divides_, request::divides_json, response::divides_json, icalc, &icalc::divides> >{};
, invoke_method<> wjrpc::method<>, :
mem_fun_handler template< typename Params, typename Result, typename I, void (I::*mem_ptr)( std::unique_ptr<Params>, std::function< void(std::unique_ptr<Result>) > ) > struct mem_fun_handler { typedef std::unique_ptr<Params> request_ptr; typedef std::unique_ptr<Result> responce_ptr; typedef std::unique_ptr< error> json_error_ptr; typedef std::function< void(responce_ptr, json_error_ptr) > jsonrpc_callback; template<typename T> void operator()(T& t, request_ptr req) const; template<typename T> void operator()(T& t, request_ptr req, jsonrpc_callback cb) const; };
, JSON-RPC , , .
, ( ), , ( ) . . , - , . . , ? - . , , . , , . , , , .
- ââ . wjrpc::invoke_method. , JSON-RPC. ââ , .
, wjrpc::invoke_method.
struct icalc { virtual ~icalc() {} virtual request::plus::ptr plus( request::plus::ptr req) = 0; virtual request::minus::ptr minus( request::minus::ptr req) = 0; virtual request::multiplies::ptr multiplies( request::multiplies::ptr req) = 0; virtual request::divides::ptr divides( request::divides::ptr req) = 0; };
wjrpc::handler<> . callback, , , , , .
calc->plus( std::move(req), [this](response::plus::ptr) {} );
std::shared_ptr<calc> pthis = this->shared_from_this(); calc->plus( std::move(req), [pthis](response::plus::ptr) {} );
, .. .
std::weak_ptr<calc> wthis = this->shared_from_this(); calc->plus( std::move(req), [wthis](response::plus::ptr) { if ( auto pthis = wthis.lock() ) { } } );
, (, ). , , callback- .
std::weak_ptr<int> w = this->_p; std::weak_ptr<calc> wthis = this->shared_from_this(); calc->plus( std::move(req), [wthis, w](response::plus::ptr) { if ( auto pthis = wthis.lock() ) { if ( nullptr == w.lock() ) return; } } );
( wjrpc)
callback- template<typename H> class owner_handler { public: typedef std::weak_ptr<int> weak_type; owner_handler() = default; owner_handler(H&& h, weak_type alive) : _handler( std::forward<H>(h) ) , _alive(alive) { } template <class... Args> auto operator()(Args&&... args) -> typename std::result_of< H(Args&&...) >::type { if ( auto p = _alive.lock() ) { return _handler( std::forward<Args>(args)... ); } return typename std::result_of< H(Args&&...) >::type(); } private: H _handler; weak_type _alive; };
( ) class owner { public: typedef std::shared_ptr<int> alive_type; typedef std::weak_ptr<int> weak_type; owner() : _alive( std::make_shared<int>(1) ) { } owner(const owner& ) = delete; owner& operator = (const owner& ) = delete; owner(owner&& ) = default; owner& operator = (owner&& ) = default; alive_type& alive() { return _alive; } const alive_type& alive() const { return _alive; } void reset() { _alive = std::make_shared<int>(*_alive + 1); } template<typename Handler> owner_handler<typename std::remove_reference<Handler>::type> wrap(Handler&& h) const { return owner_handler< typename std::remove_reference<Handler>::type >( std::forward<Handler>(h), std::weak_ptr<int>(_alive) ); } private: mutable alive_type _alive; };
. . , . , , . , .
JSON-RPC Engine
wjrpc::engine â , , jsonrpc-, . , , , wjrpc::engine. . callback-, , . wjrpc::engine, , , , .
, icalc. , plus, .
calc/calc_p.hpp #pragma once #include "icalc.hpp" class calc_p : public icalc { public: void initialize(std::shared_ptr<icalc>); virtual void plus( request::plus::ptr req, response::plus::callback cb) override; virtual void minus( request::minus::ptr req, response::minus::callback cb) override; virtual void multiplies( request::multiplies::ptr req, response::multiplies::callback cb) override; virtual void divides( request::divides::ptr req, response::divides::callback cb) override; private: template<typename ReqPtr, typename Callback> bool check_( ReqPtr& req, Callback& cb); std::shared_ptr<icalc> _next; };
calc/calc_p.cpp #include "calc_p.hpp" #include <memory> void calc_p::initialize(std::shared_ptr<icalc> next) { _next = next; } void calc_p::plus( request::plus::ptr req, response::plus::callback cb) { if ( !this->check_(req, cb)) return; req->first++; req->second++; _next->plus(std::move(req), [cb](response::plus::ptr res) { res->value++; cb(std::move(res) ); }); } void calc_p::minus( request::minus::ptr req, response::minus::callback cb) { if ( this->check_(req, cb)) _next->minus(std::move(req), std::move(cb) ); } void calc_p::multiplies( request::multiplies::ptr req, response::multiplies::callback cb) { if ( this->check_(req, cb)) _next->multiplies(std::move(req), std::move(cb) ); } void calc_p::divides( request::divides::ptr req, response::divides::callback cb) { if ( this->check_(req, cb)) _next->divides(std::move(req), std::move(cb) ); } template<typename ReqPtr, typename Callback> bool calc_p::check_( ReqPtr& req, Callback& cb) { if ( cb==nullptr ) return false; if ( req != nullptr ) return true; cb(nullptr); return false; }
, icalc, , plus, ââ. .
, : , , . , , .
, , , JSON-RPC .
JSONRPC_TAG(plus) JSONRPC_TAG(minus) JSONRPC_TAG(multiplies) JSONRPC_TAG(divides) struct method_list: wjrpc::method_list < wjrpc::call_method<_plus_, request::plus_json, response::plus_json>, wjrpc::call_method<_minus_, request::minus_json, response::minus_json>, wjrpc::call_method<_multiplies_, request::multiplies_json, response::multiplies_json>, wjrpc::call_method<_divides_, request::divides_json, response::divides_json, icalc> > {};
, , , JSON- . â icalc:
class handler : public ::wjrpc::handler<method_list> , public icalc { public: virtual void plus( request::plus::ptr req, response::plus::callback cb) override { this->template call<_plus_>( std::move(req), cb, nullptr ); } virtual void minus( request::minus::ptr req, response::minus::callback cb) override { this->template call<_minus_>( std::move(req), cb, nullptr ); } virtual void multiplies( request::multiplies::ptr req, response::multiplies::callback cb) override { this->template call<_multiplies_>( std::move(req), cb, nullptr ); } virtual void divides( request::divides::ptr req, response::divides::callback cb) override { this->template call<_divides_>( std::move(req), cb, nullptr ); } };
â call<> , , , . , . , callback nullptr.
JSON-RPC , callback nullptr, , , . JSON-RPC . , .
, , :

, , , , . , , , . , . â , . , , , .
. callback, callback, , . JSON-RPC , id JSON-RPC . callback , callback, .
calc/calc_p.cpp #include "calc/calc1.hpp" #include "calc/calc_p.hpp" #include "calc/api/plus_json.hpp" #include "calc/api/minus_json.hpp" #include "calc/api/multiplies_json.hpp" #include "calc/api/divides_json.hpp" #include <wjrpc/engine.hpp> #include <wjrpc/handler.hpp> #include <wjrpc/method.hpp> #include <iostream> #include <functional> namespace service { JSONRPC_TAG(plus) JSONRPC_TAG(minus) JSONRPC_TAG(multiplies) JSONRPC_TAG(divides) struct method_list: wjrpc::method_list < wjrpc::target<icalc>, wjrpc::invoke_method<_plus_, request::plus_json, response::plus_json, icalc, &icalc::plus>, wjrpc::invoke_method<_minus_, request::minus_json, response::minus_json, icalc, &icalc::minus>, wjrpc::invoke_method<_multiplies_, request::multiplies_json, response::multiplies_json, icalc, &icalc::multiplies>, wjrpc::invoke_method<_divides_, request::divides_json, response::divides_json, icalc, &icalc::divides> >{}; class handler: public ::wjrpc::handler<method_list> {}; typedef wjrpc::engine<handler> engine_type; } namespace gateway { JSONRPC_TAG(plus) JSONRPC_TAG(minus) JSONRPC_TAG(multiplies) JSONRPC_TAG(divides) struct method_list: wjrpc::method_list < wjrpc::call_method<_plus_, request::plus_json, response::plus_json>, wjrpc::call_method<_minus_, request::minus_json, response::minus_json>, wjrpc::call_method<_multiplies_, request::multiplies_json, response::multiplies_json>, wjrpc::call_method<_divides_, request::divides_json, response::divides_json> > {}; class handler : public ::wjrpc::handler<method_list> , public icalc { public: virtual void plus( request::plus::ptr req, response::plus::callback cb) override { this->template call<_plus_>( std::move(req), cb, nullptr ); } virtual void minus( request::minus::ptr req, response::minus::callback cb) override { this->template call<_minus_>( std::move(req), cb, nullptr ); } virtual void multiplies( request::multiplies::ptr req, response::multiplies::callback cb) override { this->template call<_multiplies_>( std::move(req), cb, nullptr ); } virtual void divides( request::divides::ptr req, response::divides::callback cb) override { this->template call<_divides_>( std::move(req), cb, nullptr ); } }; typedef wjrpc::engine<handler> engine_type; } int main() { // N1 auto prx1 = std::make_shared<calc_p>(); // auto gtw = std::make_shared<gateway::engine_type>(); // auto srv = std::make_shared<service::engine_type>(); // N2 auto prx2 = std::make_shared<calc_p>(); // auto clc = std::make_shared<calc1>(); // prx2->initialize(clc); // service::engine_type::options_type srv_opt; srv_opt.target = prx2; srv->start(srv_opt, 11); // gateway::engine_type::options_type cli_opt; gtw->start(cli_opt, 22); // gtw->reg_io(33, [srv]( wjrpc::data_ptr d, wjrpc::io_id_t /*io_id*/, wjrpc::output_handler_t handler) { std::cout << " REQUEST: " << std::string( d->begin(), d->end() ) << std::endl; srv->perform_io(std::move(d), 44, [handler](wjrpc::data_ptr d) { // JSON-RPC std::cout << " RESPONSE: " << std::string( d->begin(), d->end() ) << std::endl; handler(std::move(d) ); }); }); // ID auto gtwh = gtw->find(33); // prx1->initialize(gtwh); // plus (prx1->gtw->srv->prx2->clc) auto plus = std::make_unique<request::plus>(); plus->first = 1; plus->second = 2; prx1->plus( std::move(plus), [](response::plus::ptr res) { std::cout << "1+2=" << res->value << std::endl;; }); // plus (gtw->srv->prx2->clc) auto minus = std::make_unique<request::minus>(); minus->first = 4; minus->second = 3; gtwh->minus( std::move(minus), [](response::minus::ptr res) { std::cout << "4-3=" << res->value << std::endl;; }); }
çµæïŒ
REQUEST: {"jsonrpc":"2.0","method":"plus","params":{"first":2,"second":3},"id":1} RESPONSE: {"jsonrpc":"2.0","result":{"value":8},"id":1} 1+2=9 REQUEST: {"jsonrpc":"2.0","method":"minus","params":{"first":4,"second":3},"id":2} RESPONSE: {"jsonrpc":"2.0","result":{"value":1},"id":2} 4-3=1
, JSON-RPC 2 3 1 2. , , 8. , 9. , , , munus , .
â , , , , , , :
create_id inline wjrpc::io_id_t create_id() { static std::atomic<wjrpc::io_id_t> counter( (wjrpc::io_id_t(1)) ); return counter.fetch_add(1); }
. , :
gtw->reg_io(33, []( wjrpc::data_ptr, wjrpc::io_id_t, wjrpc::output_handler_t)
JSON-RPC , . - , , , . . . 44 â , . service::engine_type, ( , wjrpc ), .
(::pipe), , , , , - , , , . examples , , , .
wjson, , wjrpc::incoming_holder JSON-RPC . , wjrpc::handler , run-time .
wjrpc . faslib wjson . :
git clone https: