/* demo.rpc */
Simple RPC in C++, with Python binding
https://github.com/santazhang/simple-rpc http://www.yzhang.net/blog/2013-05-31-simple-rpc-1.html
First, write your .rpc
file.
/* demo.rpc */
Optional namespace for your RPC.
namespace demo;
Create an RPC service called Demo
.
service Demo {
Add an RPC method called sayhi
, with one string
type input parameter called hi
sayhi(string hi);
Add an RPC method called sum
, which adds up a
, b
and c
, and stores the result in result
.
Note that integer size is explicitly specified (i32
for 32 bit integer).
The |
sign separates input and output parameters.
sum(i32 a, i32 b, i32 c | i32 result);
There is also i8
, i16
and i64
.
is_prime(i64 num | i8 yes_or_no);
If your method does not have input parameter.
calendar_date( | string month, i32 day, i32 year);
Or maybe neither input nor output?
nop();
STL types are also supported:
pair
, vector
, list
, set
, map
, unordered_set
, unordered_map
sort(set<string> input | vector<string> sorted_output);
};
Want to use custom types? No problem :)
struct point3 {
double x;
double y;
double z;
};
service Math {
euclidean_distance(point3 a, point3 b | double result);
};
Run bin/rpcgen
against the .rpc
file you wrote.
bin/rpcgen demo.rpc
A .h
file will be generated for you, which contains RPC code stub.
It contains all the struct
, and both client side and
server side code stub for the service
you’ve defined.
For the above demo.rpc
example, a demo.h
will be generated.
In this file, you will see something like this:
class DemoService: public rpc::Service {
/* ... */
virtual void sayhi(const std::string& hi);
virtual void sum(const rpc::i32& a, const rpc::i32& b, const rpc::i32& c, rpc::i32* result);
virtual void is_prime(const rpc::i64& num, rpc::i8* yes_or_no);
virtual void calendar_date(std::string* month, rpc::i32* day, rpc::i32* year);
virtual void nop();
virtual void sort(const std::set<std::string>& input, std::vector<std::string>* sorted_output);
/* ... */
};
Those functions are to be implemented by you. Write a demo.cc
file, #include
the generated
demo.h
, and fill out the functions.
/* demo.cc */
#include "demo.h"
namespace demo {
/* ... */
void DemoService::sum(const rpc::i32& a, const rpc::i32& b, const rpc::i32& c, rpc::i32* result) {
*result = a + b + c;
}
/* ... */
}
#include
the simple-rpc library code and your RPC code.
Create the rpc::Server
object, register the service you defined, and
start the RPC server!
#include "rpc/server.h"
#include "demo.h"
int main() {
rpc::Server server;
demo::DemoService demo_svc;
server.reg(&demo_svc);
server.start("127.0.0.1:8848");
for (;;) {
sleep(1);
}
return 0;
}
In the automatically generated demo.h
file, you will find DemoProxy
class.
It makes RPC call very easy to use.
#include
the simple-rpc library code and your RPC code.
Use rpc::ClientPool
class to create connection to RPC server,
and use it to create a DemoProxy
instance.
#include "rpc/client.h"
#include "demo.h"
int main() {
rpc::ClientPool clnt_pool;
demo::DemoProxy demo(clnt_pool.get_client("127.0.0.1:8848"));
Now you can easily call the RPC functions.
demo.sayhi("hello RPC");
i32 a = 1, b = 2, c = 3;
i32 result;
demo.sum(a, b, c, &result);
printf("%d + %d + %d = %d\n", a, b, c, result);
return 0;
}
simple-rpc also supports the following features, which will be documented soon.
You can also checkout the code in test
source code folder for real world usages.
rpc::Server
.struct
/class
(defined outside .rpc
file).