| <!--toc-->
 | 
	
	
		| 
 | 
	
	
		| ## Introduction
 | 
	
	
		| 
 | 
	
	
		| [JSON-RPC](http://json-rpc.org/) is remote procedure call protocol implemented using JSON data.
 | 
	
	
		| 
 | 
	
	
		| It is a lightweight protocol that allows easy Ajax 
 | 
	
	
		| based communication between the browser and the 
 | 
	
	
		| C++ application.
 | 
	
	
		| 
 | 
	
	
		| CppCMS implements [JSON-RPC 1.0](http://json-rpc.org/wiki/specification) specifications over HTTP protocol.
 | 
	
	
		| 
 | 
	
	
		| ## JSON-RPC Service
 | 
	
	
		| 
 | 
	
	
		| ### Methods
 | 
	
	
		| 
 | 
	
	
		| Let's create a simple RPC service that allows us
 | 
	
	
		| to add and divide numbers.
 | 
	
	
		| 
 | 
	
	
		| JSON-RPC Service should be derived from `cppcms::rpc::json_rpc_server` that on the other hand
 | 
	
	
		| is derived from `cppcms::application`.
 | 
	
	
		| 
 | 
	
	
		|     class json_service : 
 | 
	
	
		|         public cppcms::rpc::json_rpc_server {
 | 
	
	
		|     public:
 | 
	
	
		| 
 | 
	
	
		| 
 | 
	
	
		| When we use JSON-RPC service we bind between PRC methods
 | 
	
	
		| and the application member functions, similarly to what
 | 
	
	
		| we done for URL dispatching.
 | 
	
	
		| 
 | 
	
	
		| In our case:
 | 
	
	
		| 
 | 
	
	
		|     json_service(cppcms::service &srv) : cppcms::rpc::json_rpc_server(srv)
 | 
	
	
		|     {
 | 
	
	
		|         bind("sum",cppcms::rpc::json_method(&json_service::sum,this),method_role);
 | 
	
	
		|         bind("div",cppcms::rpc::json_method(&json_service::div,this),method_role); 
 | 
	
	
		| 
 | 
	
	
		|     }
 | 
	
	
		| 
 | 
	
	
		| 
 | 
	
	
		| Similarly to URL mapper we connect the "sum" meber
 | 
	
	
		| Similarly to URL mapper we connect the "sum" member
 | 
	
	
		| function to "sum" JSON-RPC method and specify that this
 | 
	
	
		| is a method that should return a value (not notification)
 | 
	
	
		| 
 | 
	
	
		| Now we implement our service:
 | 
	
	
		| 
 | 
	
	
		|     void sum(int x,int y)
 | 
	
	
		|     {
 | 
	
	
		|         return_result(x+y);
 | 
	
	
		|     }
 | 
	
	
		|     void div(int x,int y)
 | 
	
	
		|     {
 | 
	
	
		|         if(y==0)
 | 
	
	
		|             return_error("Division by zero");
 | 
	
	
		|         else
 | 
	
	
		|             return_result(x/y);
 | 
	
	
		|     }
 | 
	
	
		| 
 | 
	
	
		| Please note, out functions create two types of the
 | 
	
	
		| response: normal result response and error response
 | 
	
	
		| as defined by JSON-RPC specification.
 | 
	
	
		| 
 | 
	
	
		| The parameters of the method call are automatically
 | 
	
	
		| converted to appropriate C++ object. If the conversion
 | 
	
	
		| can't be done, the error would be automatically returned
 | 
	
	
		| and the functions would not be called. Similarly integer
 | 
	
	
		| result is automatically converted to `cppcms::json::value`
 | 
	
	
		| 
 | 
	
	
		| Similarly to the way we mount `cppcms::application` based
 | 
	
	
		| classes we create our JSON-RPC service:
 | 
	
	
		| 
 | 
	
	
		|     cppcms::service srv(argc,argv);
 | 
	
	
		|     srv.applications_pool().mount( cppcms::applications_factory<json_service>());
 | 
	
	
		|     srv.run();
 | 
	
	
		| 
 | 
	
	
		| ### Client Side Code
 | 
	
	
		| 
 | 
	
	
		| Let's create a small form that would handle RPC request
 | 
	
	
		| for us:
 | 
	
	
		| 
 | 
	
	
		|     <form onsubmit="return call();">
 | 
	
	
		|     <p>
 | 
	
	
		|         <input type="text" id="x" />
 | 
	
	
		|         <input type="submit" value="/" />
 | 
	
	
		|         <input type="text" id="y" /> =
 | 
	
	
		|         <span id="result"></span>
 | 
	
	
		|     </p>
 | 
	
	
		|     </form>
 | 
	
	
		| 
 | 
	
	
		| Now let's implement JSON-RPC call using XmlHTTPRequest -  function call:
 | 
	
	
		| 
 | 
	
	
		|     function call() {
 | 
	
	
		|       ...
 | 
	
	
		|     }
 | 
	
	
		| 
 | 
	
	
		| First we create the XMLHttpRequest object and set
 | 
	
	
		| essential content-type "application/json":
 | 
	
	
		| 
 | 
	
	
		|     var xhr = new XMLHttpRequest();
 | 
	
	
		|     xhr.open("post", '/rpc');
 | 
	
	
		|     // Required by JSON-RPC over HTTP
 | 
	
	
		|     xhr.setRequestHeader("Content-Type","application/json");
 | 
	
	
		| 
 | 
	
	
		| Then we configure our JSON-RPC request:
 | 
	
	
		| 
 | 
	
	
		|     // It is better to use real formatter like JSON.js
 | 
	
	
		|     var x=parseInt(document.getElementById('x').value);
 | 
	
	
		|     var y=parseInt(document.getElementById('y').value);
 | 
	
	
		|     var request = '{"method":"div","params":[' + x + ',' + y +'],"id":1}';
 | 
	
	
		| 
 | 
	
	
		| Define `onreadystatechange` callback and send the request:
 | 
	
	
		| 
 | 
	
	
		|     xhr.onreadystatechange = function() {
 | 
	
	
		|      ...
 | 
	
	
		|     }
 | 
	
	
		|     xhr.send(request);
 | 
	
	
		|     return false;
 | 
	
	
		| 
 | 
	
	
		| 
 | 
	
	
		| The callback function would look like:
 | 
	
	
		| 
 | 
	
	
		|     if (xhr.readyState === 4) {
 | 
	
	
		|         var res;
 | 
	
	
		|         if(xhr.status === 200) {
 | 
	
	
		|             // Don't call eval in real code use some parser
 | 
	
	
		|             var result = eval('(' + xhr.responseText + ')');
 | 
	
	
		|             if(result.error==null) {
 | 
	
	
		|                 res = result.result;
 | 
	
	
		|             }
 | 
	
	
		|             else {
 | 
	
	
		|                 res = result.error;
 | 
	
	
		|             }
 | 
	
	
		|         }
 | 
	
	
		|         else {
 | 
	
	
		|             res = 'Invalid Status ' + xhr.status;
 | 
	
	
		|         }
 | 
	
	
		|         document.getElementById('result').innerHTML = res;
 | 
	
	
		|     }
 | 
	
	
		| 
 | 
	
	
		| Upon sucesseful completion of XHR we parse
 | 
	
	
		| Upon successful completion of XHR we parse
 | 
	
	
		| the response and setup the result value.
 | 
	
	
		| 
 | 
	
	
		| ### Notifications
 | 
	
	
		| 
 | 
	
	
		| JSON-RPC specifies two types of remote calls:
 | 
	
	
		| 
 | 
	
	
		| - methods - the calls that return certain values
 | 
	
	
		| - notification - `void` like calls that do not return
 | 
	
	
		| result.
 | 
	
	
		| 
 | 
	
	
		| The two functions above (div and sum) were methods.
 | 
	
	
		| If we want to have notifications we can create them
 | 
	
	
		| as simple as methods:
 | 
	
	
		| 
 | 
	
	
		|     bind("notify",cppcms::rpc::json_method(&json_service::notify,this),notification_role);
 | 
	
	
		|     bind("both",cppcms::rpc::json_method(&json_service::both,this));
 | 
	
	
		| 
 | 
	
	
		| Notification method `notify` function should not call `return_result` or `return_error`, on the other hand `both` should return the result if required:
 | 
	
	
		| 
 | 
	
	
		|     void notify(std::string msg)
 | 
	
	
		|     {
 | 
	
	
		|         std::cout << "We got notification " << msg << std::endl;
 | 
	
	
		|     }
 | 
	
	
		|     void both(std::string msg)
 | 
	
	
		|     {
 | 
	
	
		|         if(notification())
 | 
	
	
		|             std::cout << "We got notification " << msg << std::endl;
 | 
	
	
		|         else
 | 
	
	
		|             return_result("call:"+msg);
 | 
	
	
		|     }
 | 
	
	
		| 
 | 
	
	
		| 
 | 
	
	
		| ## JSON-PRC Clients
 | 
	
	
		| 
 | 
	
	
		| There are many client side toolkits like Dojo that provide
 | 
	
	
		| sophisticated JSON-RPC clients. Feel free to choose
 | 
	
	
		| whatever client you like as long as it supports
 | 
	
	
		| JSON-RPC 1.0. 
 | 
	
	
		| 
 | 
	
	
		| **Note:** JSON-RPC 1.0 is the only valid standard, JSON-RPC 2.0 is still draft and relays on JSON-Schema that is 
 | 
	
	
		| draft-standard as well, that is why it is not implemented.
 | 
	
	
		| 
 | 
	
	
		| You can also find a simple JSON-RPC client in CppCMS
 | 
	
	
		| sources under `contrib/client_side/jsonrpc` | 
	
	
		| sources under `contrib/client_side/jsonrpc`
 | 
	
	
		| 
 | 
	
	
		| ---
 | 
	
	
		| 
 | 
	
	
		| ← [JSON][prev]
 | 
	
	
		| | [Top](#maincontent)
 | 
	
	
		| | [Internationalization and Localization][next] →
 | 
	
	
		| 
 | 
	
	
		| [prev]: /wikipp/en/page/cppcms_1x_json
 | 
	
	
		| [next]: /wikipp/en/page/cppcms_1x_i18n_and_l10n |