int main(int argc, char* argv[]) { try { // initialize logging - this reads the file log.xml from the current directory log_init(); // read the command line options cxxtools::Arg<std::string> ip(argc, argv, 'i'); // option -i <ip-addres> defines the address where to find the server cxxtools::Arg<bool> binary(argc, argv, 'b'); cxxtools::Arg<bool> json(argc, argv, 'j'); cxxtools::Arg<bool> jsonhttp(argc, argv, 'J'); cxxtools::Arg<std::size_t> timeout(argc, argv, 't', cxxtools::RemoteClient::WaitInfinite); cxxtools::Arg<unsigned short> port(argc, argv, 'p', binary ? 7003 : json ? 7004 : 7002); // we need a selector, which controls the network activity cxxtools::Selector selector; // Normally we would define just one rpc client for the protocol we use but // here we want to demonstrate, that it is just up to the client, which protocol // is used for the remote call. // One client can run just one request at a time. To run parallel requests // we need 2 clients. So we define 2 clients for each protocol. // define a xlmrpc client cxxtools::xmlrpc::HttpClient xmlrpcClient1(selector, ip, port, "/xmlrpc"); cxxtools::xmlrpc::HttpClient xmlrpcClient2(selector, ip, port, "/xmlrpc"); // and a binary rpc client cxxtools::bin::RpcClient binaryClient1(selector, ip, port); cxxtools::bin::RpcClient binaryClient2(selector, ip, port); // and a tcp json rpc client cxxtools::json::RpcClient jsonClient1(selector, ip, port); cxxtools::json::RpcClient jsonClient2(selector, ip, port); // and a http json rpc client cxxtools::json::HttpClient httpJsonClient1(selector, ip, port, "/jsonrpc"); cxxtools::json::HttpClient httpJsonClient2(selector, ip, port, "/jsonrpc"); // now se select the client depending on the command line flags cxxtools::RemoteClient& client1( binary ? static_cast<cxxtools::RemoteClient&>(binaryClient1) : json ? static_cast<cxxtools::RemoteClient&>(jsonClient1) : jsonhttp ? static_cast<cxxtools::RemoteClient&>(httpJsonClient1) : static_cast<cxxtools::RemoteClient&>(xmlrpcClient1)); cxxtools::RemoteClient& client2( binary ? static_cast<cxxtools::RemoteClient&>(binaryClient2) : json ? static_cast<cxxtools::RemoteClient&>(jsonClient2) : jsonhttp ? static_cast<cxxtools::RemoteClient&>(httpJsonClient2) : static_cast<cxxtools::RemoteClient&>(xmlrpcClient2)); // define remote procedure with dobule return value and two double parameters cxxtools::RemoteProcedure<double, double, double> add1(client1, "add"); cxxtools::RemoteProcedure<double, double, double> add2(client2, "add"); // initiate the execution of our method add1.begin(5, 6); add2.begin(1, 2); // Calling RemoteProcedure::end will run the underlying event loop until // the remote procedure is finished and return the result. // In case of a error, an exception is thrown. // Note that waiting for the end of one remote procedure will also start // and maybe finish the second remote procedure. double result1 = add1.end(timeout); std::cout << "result1=" << result1 << std::endl; // Here we run the loop again until the second procedure is finished. It // may well be, that the procedure is already finished and we get the // result immediately. double result2 = add2.end(timeout); std::cout << "result2=" << result2 << std::endl; } catch (const std::exception& e) { std::cerr << "error: " << e.what() << std::endl; } }
int main(int argc, char* argv[]) { try { log_init("rpcbenchclient.properties"); cxxtools::Arg<std::string> ip(argc, argv, 'i'); cxxtools::Arg<unsigned> threads(argc, argv, 't', 4); cxxtools::Arg<unsigned> concurrentRequestsPerThread(argc, argv, 'c', 4); cxxtools::Arg<bool> xmlrpc(argc, argv, 'x'); cxxtools::Arg<bool> binary(argc, argv, 'b'); cxxtools::Arg<bool> json(argc, argv, 'j'); cxxtools::Arg<bool> jsonhttp(argc, argv, 'J'); cxxtools::Arg<unsigned short> port(argc, argv, 'p', binary ? 7003 : json ? 7004 : 7002); BenchClient::numRequests(cxxtools::Arg<unsigned>(argc, argv, 'n', 10000)); BenchClient::vectorSize(cxxtools::Arg<unsigned>(argc, argv, 'v', 0)); BenchClient::objectsSize(cxxtools::Arg<unsigned>(argc, argv, 'o', 0)); if (!xmlrpc && !binary && !json && !jsonhttp) { std::cerr << "usage: " << argv[0] << " [options]\n" "options:\n" " -l ip set ip address of server (default: localhost)\n" " -p number set port number of server (default: 7002 for http, 7003 for binary and 7004 for json)\n" " -x use xmlrpc protocol\n" " -b use binary rpc protocol\n" " -j use json rpc protocol\n" " -J use json rpc over http protocol\n" " -c number concurrent request per thread (default: 4)\n" " -t number set number of threads (default: 4)\n" " -n number set number of requests (default: 10000)\n" "one protocol must be selected\n" << std::endl; return -1; } BenchClients clients; XmlRpcClientCreator xmlRpcClientCreator(ip, port, "/xmlrpc"); JsonHttpClientCreator jsonHttpClientCreator(ip, port, "/jsonrpc"); JsonRpcClientCreator jsonRpcClientCreator(ip, port); BinRpcClientCreator binRpcClientCreator(ip, port); ClientCreator& clientCreator = binary ? static_cast<ClientCreator&>(binRpcClientCreator) : json ? static_cast<ClientCreator&>(jsonRpcClientCreator) : jsonhttp ? static_cast<ClientCreator&>(jsonHttpClientCreator) : static_cast<ClientCreator&>(xmlRpcClientCreator); while (clients.size() < threads) { clients.push_back(new BenchClient(clientCreator, concurrentRequestsPerThread)); } cxxtools::Clock cl; cl.start(); for (BenchClients::iterator it = clients.begin(); it != clients.end(); ++it) (*it)->start(); for (BenchClients::iterator it = clients.begin(); it != clients.end(); ++it) (*it)->join(); cxxtools::Timespan t = cl.stop(); std::cout << BenchClient::numRequests() << " requests in " << t.totalMSecs()/1e3 << " s => " << (BenchClient::requestsStarted() / (t.totalMSecs()/1e3)) << "#/s\n" << BenchClient::requestsFinished() << " finished " << BenchClient::requestsFailed() << " failed" << std::endl; for (BenchClients::iterator it = clients.begin(); it != clients.end(); ++it) delete *it; } catch (const std::exception& e) { std::cerr << e.what() << std::endl; } }