# rest_rpc **Repository Path**: flx413/rest_rpc ## Basic Information - **Project Name**: rest_rpc - **Description**: fork from https://github.com/qicosmos/rest_rpc - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2025-12-06 - **Last Updated**: 2025-12-06 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # rest_rpc | OS (Compiler Version) | Status | |------------------------------------------------|----------------------------------------------------------------------------------------------------------| | Ubuntu 22.04 (clang 14.0.0) | ![win](https://github.com/qicosmos/rest_rpc/actions/workflows/linux_clang.yml/badge.svg?branch=master) | | Ubuntu 22.04 (gcc 11.2.0) | ![win](https://github.com/qicosmos/rest_rpc/actions/workflows/linux_gcc.yml/badge.svg?branch=master) | | macOS Monterey 12 (AppleClang 14.0.0.14000029) | ![win](https://github.com/qicosmos/rest_rpc/actions/workflows/mac.yml/badge.svg?branch=master) | | Windows Server 2022 (MSVC 19.33.31630.0) | ![win](https://github.com/qicosmos/rest_rpc/actions/workflows/windows.yml/badge.svg?branch=master) | c++20, high performance, cross platform, easy to use rpc framework. It's so easy to love RPC. Modern C++开发的RPC库就是这么简单好用! # rest_rpc简介 rest_rpc是一个高性能、易用、跨平台、header only的基于c++20 协程的rpc 库,它的目标是让tcp通信变得非常简单易用,即使不懂网络通信的人也可以直接使用它。它依赖header-only的standalone [asio](https://github.com/chriskohlhoff/asio)(tag:asio-1-36-0) 可以快速上手,使用者只需要关注自己的业务逻辑即可。 # 编译器版本 需要完全支持c++20 的编译器: gcc12+, clang15+, msvc2022 # 谁在用rest_rpc 1. 博世汽车 [在这里增加用户](https://github.com/qicosmos/rest_rpc/wiki/%E4%BD%BF%E7%94%A8rest_rpc%E7%9A%84%E7%94%A8%E6%88%B7%E5%88%97%E8%A1%A8) # rest_rpc的特点 ## 易 rest_rpc为用户提供了非常简单易用的接口,几行代码就可以实现rpc通信了,来看第一个例子 ### 一个加法的rpc服务 ```cpp //服务端注册加法rpc服务 int add(rpc_conn conn, int a, int b) { return a + b; } int main(){ rpc_server server("127.0.0.1:9004", std::thread::hardware_concurrency()); server.register_handler(); server.start(); } ``` ```cpp //客户端调用加法的rpc服务 int main(){ auto rpc_call = []() -> asio::awaitable { rpc_client client; auto ec = co_await client.connect("127.0.0.1:9004"); if(ec) { REST_LOG_ERROR << ec.message(); co_return; } auto r = co_await client.call(1, 2); if(r.ec == rpc_errc::ok) { REST_LOG_INFO << "call result: " << r.value; assert(r.value == 3); } }; sync_wait(rpc_call()); } ``` ### 获取一个对象的rpc服务 ```cpp //1.先定义person对象 struct person { int id; std::string name; int age; }; //2.提供rpc服务 person get_person(person p) { p.name = "jack"; return p; } int main(){ rpc_server server("127.0.0.1:9004", std::thread::hardware_concurrency()); server.register_handler(); server.start(); } ``` ```cpp //客户端调用获取person对象的rpc服务 int main(){ auto rpc_call = []() -> asio::awaitable { rpc_client client; auto ec = co_await client.connect("127.0.0.1:9004"); if(ec) { REST_LOG_ERROR << ec.message(); co_return; } person p{1, "tom", 20}; auto r = co_await client.call(p); if(r.ec==rpc_errc::ok) { REST_LOG_INFO << "call result: " << r.value.name; assert(r.value.name == "jack"); } }; sync_wait(rpc_call()); } ``` ## 酷 rest_rpc 比较有特色的一个功能是支持订阅发布。 以订阅某个topic为例: server 端代码: ```cpp void publish() { rpc_server server("127.0.0.1:9004", 4); server.async_start(); REST_LOG_INFO << "will pubish, waiting for input"; auto pub = [&]() -> asio::awaitable { std::string str; while (true) { std::cin >> str; if(str == "quit") { break; } // 向客户端发布一个string,你也可以发布一个对象,内部会自动序列化 co_await server.publish("topic1", str); } }; sync_wait(pub()); } client 端代码: ```cpp void subscribe() { REST_LOG_INFO << "will subscribe, waiting for publish"; auto sub = [&]() -> asio::awaitable { rpc_client client; co_await client.connect("127.0.0.1:9004"); while (true) { // 订阅topic1,库会自动将结果反序列化为std::string, 如果publish是一个person对象,则subscribe参数填person,内部会自动反序列化 auto [ec, result] = co_await client.subscribe("topic1"); if (ec != rpc_errc::ok) { REST_LOG_ERROR << "subscribe failed: " << make_error_code(ec).message(); break; } REST_LOG_INFO << result; } }; sync_wait(sub()); } ``` ## 快 rest_rpc是目前最快的rpc库,具体和grpc和brpc做了性能对比测试,rest_rpc性能是最高的,远超grpc。 性能测试代码在这里: https://github.com/qicosmos/rest_rpc/tree/master/tests/bench.cpp ## 活 rest_rpc 也是比较灵活的,允许用户替换默认的序列化库。 rest_rpc 默认使用yalantinglibs的struct_pack 去做系列化/反序列化的,它的性能非常好。 rest_rpc 也支持用户使用自己的序列化库,只需要去实现一个序列化和一个反序列化函数。 ```cpp namespace user_codec { // adl lookup in user_codec namespace template std::string serialize(rest_adl_tag, Args &&...args) { msgpack::sbuffer buffer(2 * 1024); if constexpr (sizeof...(Args) > 1) { msgpack::pack(buffer, std::forward_as_tuple(std::forward(args)...)); } else { msgpack::pack(buffer, std::forward(args)...); } return std::string(buffer.data(), buffer.size()); } template T deserialize(rest_adl_tag, std::string_view data) { try { static msgpack::unpacked msg; msgpack::unpack(msg, data.data(), data.size()); return msg.get().as(); } catch (...) { return T{}; } } } // namespace user_codec ``` 实现这两个函数之后rest_rpc 将会使用自定义的序列化/反序列化函数了。 # rest_rpc的更多用法 rest_rpc 支持零拷贝发数据,以echo函数为例: ```cpp std::string_view echo(std::string_view str) { return str; } ``` 假如用户希望发送很大的一个数据,可能有数GB,如果按照常规的做法,需要先序列化,这样就存在内存拷贝,rest_rpc 针对这种场景专门做了优化,当client调用rpc函数时传入的是std::string_view 时, rest_rpc 将不会对传入的数据做拷贝,也不会去做序列化,直接通过socket发送到服务端。 rpc函数的返回类型为std::string_view 时,client收到的响应数据也不会做反序列化和内存拷贝,直接返回的是收到的socket 数据。 这样就可以实现rpc的零拷贝数据发送了,能获得最佳的性能。事实上当用户的rpc函数的参数为单参数并且类型为基本类型(字符串和数字类型)时,rest_rpc 不会做序列化,以获得更好的性能,只有多参数或者结构体时才会去序列化。 更多例子可以参考rest_rpc的example: https://github.com/qicosmos/rest_rpc/tree/master/examples ## 社区和群 http://purecpp.cn qq群:546487929