Main  /  Edit version 1  /  Edit version 2  /   /  Users Area

Difference "JSON RPC" ver. 1 versus ver. 2

Content:

<!--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
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
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
<!--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
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
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`

Sidebar:

## Related
- [JSON](/wikipp/en/page/cppcms_1x_json)
## Related
- [JSON](/wikipp/en/page/cppcms_1x_json)
← [JSON](http://cppcms.com/wikipp/en/page/cppcms_1x_json)
[Internationalization and Localization](http://cppcms.com/wikipp/en/page/cppcms_1x_i18n_and_l10n)→

About

CppCMS is a web development framework for performance demanding applications.

Support This Project

SourceForge.net Logo

Поддержать проект

CppCMS needs You


Navigation

Main Page


Valid CSS | Valid XHTML 1.0