Skip to content
This repository has been archived by the owner on Sep 22, 2022. It is now read-only.
/ rttr_rpc Public archive

JSON-RPC 2.0 server based on C++ runtime reflection

License

Notifications You must be signed in to change notification settings

kdeyev/rttr_rpc

Repository files navigation

RTTR-RPC

JSON-RPC 2.0 server based on C++ runtime reflection

Overview

RTTR-RPC is a JSON-RPC 2.0 framework built on top of RTTR C++ reflection library, which allows binding of existing C++ object to a JSON-RPC service. RTTR-RPC uses JSON Schema Service Descriptor for providing a service discovery functionality. rpc-web-channel.js uses the JSON Schema Service Descriptor for JavaScript stubs generating in run-time and uses JSON Schema for UI form generation.

Motivation

C++ reflection

You have a sctuct/class:

struct Calculator {
    Calculator(){};
    double sum(double val1, double val2) {
        return val1 + val2;
    };
};

You add a reflection to your C++ class using non-intrusive syntax:

RTTR_REGISTRATION {
    rttr::registration::class_<Calculator>("Calculator")(
        // class meta data
        rttr::metadata(rttr_rpc::meta_data_type::thread_safe, true), 
        rttr::metadata(rttr_rpc::meta_data_type::description, "Calculator service obj"),
        rttr::metadata(rttr_rpc::meta_data_type::version, "7.0")
    )
    
    .method("sum", rttr::select_overload<double(double, double)>(&Calculator::sum))(
        rttr::parameter_names("val1", "val2"),
        rttr::metadata(rttr_rpc::meta_data_type::description, "Summation of scalars")
    );
}

C++ object binding to JSON-RPC service

Bind a class instance to RTTR-RPC service repository:

// service repository
rttr_rpc::core::repository repo;

// an instance of your service
Calculator calc;

// bind the object to the service repository
repo.add_service("calc", calc);

invoke the instance method using JSON-RPC request:

// example of JSON-RPC request
auto request = std::make_shared <jsonrpc::request> (3, "calc.sum", R"([42.0,24.0])");

// process the JSON-RPC request
auto response = repo.process_message(request);

It's also allowed to use named arguments:

// example of JSON-RPC request with named arguments
auto request = std::make_shared <jsonrpc::request> (3, "calc.sum", R"({"val1": 42.0, "val2": 24.0)");

// process the JSON-RPC request
auto response = repo.process_message(request);

JavaScript client using rpc-web-channel

rpc-web-channel uses the JSON Schema Service Descriptor for building JS stubs on client side

new rpc-web-channel(jrpc, function(services) {
    let calc = services.calc;

    calc.sum(42.0, 24.0).then(function (result) {
        // do something with the result
    });
};

Automatic UI forms generation

rpc-web-channel utilizes the JSON Schema Service Descriptor format for discovering service list on a Service Descriptor compatible JSON-RPC 2.0 server and uses the React Jon Schema Form for the UI forms generation. A generated UI Form allows specifying parameter values and invokes a server-side method using rpc-web-channel.

An example of generated form:

calc_sum_double calc_sum_double

Parameter values validation:

calc_sum_uchar

Composite parameters:

calc_dot

Server invocation:

calc_dot

Look at rpc-web-channel React From example for details.

Components

Build

Build RTTR

  1. cd 3rd_party/rttr
  2. mkdir build && cd mkdir
  3. cmake -DCMAKE_INSTALL_PREFIX:PATH=../install -G "Visual Studio 15 2017 Win64" ..
  4. cmake --build . --target install

Build RTTR-RPC

  1. mkdir build && cd mkdir
  2. cmake -G "Visual Studio 15 2017 Win64" ..
  3. cmake --build . --target install

References