a tiny C++14 rpc library, supports all platforms (macOS, Linux, Windows, iOS, Android, etc.) and most microchips ( Arduino, STM32, ESP32/ESP8266, etc.)
Recommend TCP-based implementation: asio_net
Full-feature rpc frameworks (e.g. gRPC
and bRPC
) are very complex and not suitable for embedded systems.
This project offers a lightweight and user-friend rpc library that is better suited for one-to-one rpc calls. It supports all platforms and a wide range of microchips, including Arduino, STM32, ESP32/ESP8266, and more.
Note: This project only offers the protocol layer and API, it does not include the implementation of the transport layer. For TCP-based implementation: asio_net
tcp socket
, serial port
, etc.)flatbuffers
and nlohmann::json
co_await
, depend on C++20
and asio
, or custom implementationdispose
for automatic cancel requestC++
Rust
websocket
.tcp socket
, serial port
, etc., message pack and unpack need to be implemented.
Or you can use stream_connection.// The Receiver
rpc->subscribe("cmd", [](const std::string& msg) -> std::string {
assert(msg == "hello");
return "world";
});
// The Sender
rpc->cmd("cmd")
->msg(std::string("hello"))
->rsp([](const std::string& rsp) {
assert(rsp == "world");
})
->call();
// The Receiver
rpc->subscribe("cmd", [&](request_response<std::string, std::string> rr) -> asio::awaitable<void> {
assert(rr->req == "hello");
asio::steady_timer timer(context);
timer.expires_after(std::chrono::seconds(1));
co_await timer.async_wait();
rr->rsp("world");
}, scheduler_asio_coroutine);
// The Sender
// use C++20 co_await with asio, or you can use custom async implementation, and co_await it!
auto rsp = co_await rpc->cmd("cmd")->msg(std::string("hello"))->async_call<std::string>();
assert(rsp.data == "world");
Inspect the code for more details: rpc_s_coroutine.cpp and rpc_c_coroutine.cpp
msg
and rsp
support any serializable type, refer to Serialization.High-performance and memory-saving binary serialization.
Fist of all, I want to keep rpc_core
library standalone, without any dependencies, except for STL.
Moreover, these serialization libraries do not align with my design goals:
Of course, when communicating across languages, it is recommended to use the above serialization libraries!
Finally, it also provides a way to use thirdparty serialization libraries directly, refer to Serialization Plugins.
For example, user data:
struct Type {
uint8_t id = 1;
uint8_t age = 18;
std::string name = "test";
};
json: {"id":1,"age":18,"name":"test"}
library | bytes |
---|---|
json | 31 |
flatbuffers | 44 |
protobuf | 10 |
msgpack | 8 |
rpc_core | 8 |
#include "rpc_core/serialize.hpp"
struct TestStruct {
uint8_t a;
std::string b;
OtherType c
// RPC_CORE_DEFINE_TYPE_INNER(a, b, c);
};
RPC_CORE_DEFINE_TYPE(TestStruct, a, b, c);
choose RPC_CORE_DEFINE_TYPE
or RPC_CORE_DEFINE_TYPE_INNER
for private member variable.
flatbuffers.hpp
Supports using types generated by flatbuffers
directly as message
(add the option --gen-object-api
when using flatc
)
json_msg.hpp
Supports using types supported by nlohmann/json directly as message
(the to_json/from_json
rules in nlohmann/json
need to be satisfied, and use DEFINE_JSON_CLASS
).
json.hpp
A flexible way to use nlohmann/json
This project is licensed under the MIT license.