In addition to serving RCF clients, RCF::RcfServer
let's you expose C++ server functionality to JSON-RPC
clients, by functioning as a JSON-RPC server.
To enable JSON-RPC support, you will need to download the JSON
Spirit library, set the relevant compiler include paths for it, and
define RCF_USE_JSON
when building
RCF (see Building).
To serve JSON-RPC clients, you will need a RcfServer
with an HTTP or HTTPS endpoint, configured to receive JSON-RPC requests instead
of regular RCF requests:
RCF::RcfServer server; server.addEndpoint( RCF::HttpEndpoint(80) ) .setRpcProtocol(RCF::Rp_JsonRpc);
For each JSON-RPC service you want to implement, you need to define a function
that takes a RCF::JsonRpcRequest
and returns a RCF::JsonRpcResponse
:
void JsonPrint( const RCF::JsonRpcRequest & request, RCF::JsonRpcResponse & response) { // ... }
Use RcfServer::bindJsonRpc()
to expose this function as a JSON-RPC service, with the given method name:
server.bindJsonRpc( boost::bind(&JsonPrint, _1, _2), "JsonPrint");
In the servant implemenation of the JSON-RPC request (in this case the JsonPrint()
function), you can use JsonRpcRequest
to access the JSON-RPC attributes and JSON-RPC parameters of the request. To
send a response back to the client, fill out the JsonRpcResponse
object with the relevant details:
void JsonPrint( const RCF::JsonRpcRequest & request, RCF::JsonRpcResponse & response) { // Print out all the strings passed in, and return the number of // characters printed. int charsPrinted = 0; const json_spirit::Array & params = request.getJsonParams(); for (std::size_t i=0; i<params.size(); ++i) { const std::string & s = params[i].get_str(); std::cout << "I_HelloWorld service: " << s << std::endl; charsPrinted += s.size(); } // Return number of characters printed. json_spirit::mObject & responseObj = response.getJsonResponse(); responseObj["result"] = charsPrinted; }
RCF supports JSON-RPC over both HTTP and HTTPS. When using JSON-RPC over HTTPS, you will need to configure a certificate for the server. This is done in the same way as when configuring the SSL transport protocol (see Transport protocols). For example:
RCF::RcfServer server; server.addEndpoint( RCF::HttpsEndpoint(443) ) .setRpcProtocol(RCF::Rp_JsonRpc); // Assume we are using Schannel on Windows. RCF::CertificatePtr serverCertPtr( new RCF::PfxCertificate( "C:\\ServerCert.p12", "password", "CertificateName") ); server.setCertificate(serverCertPtr);
Finally, as RcfServer
instances
support multiple transports (see Transports),
you can serve regular RCF clients as well as JSON-RPC clients, from the same
RcfServer
:
RCF::RcfServer server; // Serve JSON-RPC clients over HTTP on port 80. server.addEndpoint( RCF::HttpEndpoint(80) ) .setRpcProtocol(RCF::Rp_JsonRpc); server.bindJsonRpc( boost::bind(&JsonPrint, _1, _2), "JsonPrint"); // Serve RCF clients over TCP on port 50001. server.addEndpoint( RCF::TcpEndpoint(50001) ); // Serve RCF clients over HTTP on port 50002. server.addEndpoint( RCF::HttpEndpoint(50002) ); HelloWorldImpl helloWorldImpl; server.bind<I_HelloWorld>(helloWorldImpl); server.start();