当前位置: 首页 > news >正文

2510C++,rest_rpc

原文

这次升级改动主要有以下几个方面:
1,去掉回调全部换成C++20``协程;
2,基于协程订阅发布.
3,序化库换成性能更好的yalantinglibsstruct_pack
4,更安全的编译期检查.
5,提升性能
6,支持用户自定义序化

现在来看看最新的rest_rpc的基本用法:

基本用法

    //定义rpc函数
int add(rpc_conn conn, int a, int b) { return a + b; }
std::string_view echo(std::string_view str) { return str; }
int main(){rpc_server server("127.0.0.1:9004", std::thread::hardware_concurrency());server.register_handler<add>();server.register_handler<echo>();server.start();
}int main(){auto rpc_call = []() -> asio::awaitable<void> {rpc_client client;co_await client.connect("127.0.0.1:9004");auto r = co_await client.call<add>(1, 2);assert(r.value == 3);auto r1 = co_await client.call<echo>("test");assert(r.value == "test");};sync_wait(rpc_call());
}

最简单rpc服务几行代码就行了.rpc函数也可按协程函数定义.

asio::awaitable<std::string_view> echo_coro(std::string_view str) {co_return str;
}int main(){rpc_server server("127.0.0.1:9004", std::thread::hardware_concurrency());server.register_handler<echo_coro>();server.async_start();auto rpc_call = []() -> asio::awaitable<void> {rpc_client client;co_await client.connect("127.0.0.1:9004");auto r1 = co_await client.call<echo_coro>("test");assert(r.value == "test");};sync_wait(rpc_call());
}

这里使用的是asio协程,也是根据社区同学的建议使用asio协程,因为可很容易于和其它的基于asio协程mysql,redis等库结合起来.

特色功能

rest_rpc的特色是支持订阅发布.
客户订阅某个主题,服务端向客户发布.

struct person {int id;std::string name;int age;
};
int main() {auto sub = [&]() -> asio::awaitable<void> {rpc_client client;co_await client.connect("127.0.0.1:9004");while (true) {auto [ec, result] = co_await client.subscribe<person>("topic1");if (ec != rpc_errc::ok) {REST_LOG_ERROR << "subscribe failed: " << make_error_code(ec).message();break;}assert(result.name == "tom");}};sync_wait(sub());
}
void publish() {rpc_server server("127.0.0.1:9004", 4);server.async_start();auto pub = [&]() -> asio::awaitable<void> {std::string str;while (true) {std::cin >> str;if (str == "quit") {break;}co_await server.publish("topic1", person{1, "tom", 20});}};sync_wait(pub());
}

自定义序化

rest_rpc默认使用的是yalantinglibs.struct_pack,也可按自己的序化库替换它,替换也很简单,定义两个函数即可.比如想替换成msgpack去序化/反序化.

namespace user_codec {
template <typename... Args>
std::string serialize(rest_adl_tag, Args &&...args) {in_user_pack = true;msgpack::sbuffer buffer(2 * 1024);if constexpr (sizeof...(Args) > 1) {msgpack::pack(buffer,std::forward_as_tuple(std::forward<Args>(args)...));} else {msgpack::pack(buffer, std::forward<Args>(args)...);}return std::string(buffer.data(), buffer.size());
}
template <typename T> T deserialize(rest_adl_tag, std::string_view data) {try {in_user_unpack = true;static msgpack::unpacked msg;msgpack::unpack(msg, data.data(), data.size());return msg.get().as<T>();} catch (...) {return T{};}
}
}//user_codec名间

user_codec名字空间下实现序化/反序化函数即可.

零拷贝传输

假如用户希望发送很大的一个数据,可能有数GB,如果按普通的做法,需要先序化,这样就有内存拷贝,rest_rpc针对该场景专门做了优化,

客户调用rpc函数时传入的是std::string_view时,rest_rpc将不会拷贝传入的数据,也不会序化它,而是直接通过套接字发送到服务端.

rpc函数的返回类型std::string_view时,客户不会反序化和内存拷贝收到的响应数据,而是直接返回的是收到的套接字数据.
这样就可实现rpc零拷贝数据发送了,能取得最佳的性能.

性能

rest_rpc的性能比grpcbrpc更好,

http://www.dtcms.com/a/503047.html

相关文章:

  • [Power BI] 卡片图与多行卡
  • 大模型理论概述
  • 做风险投资网站商城网站建设策划书
  • 【STM32项目开源】STM32单片机智能家居控制系统
  • 【设计模式】Java规则树重构复杂业务逻辑
  • 网络:传输层协议UDP和TCP
  • 从Excel姓名匹配案例学Python:由点及面的系统化学习指南
  • 建网站的专业公司家教网站制作
  • 赋能金融科技:基于AWS的云上量化交易解决方案,让策略研发与部署效率倍增
  • 洛谷 P1012 [NOIP 1998 提高组] 拼数
  • P12954 [GCJ Farewell Round #2] Railroad Maintenance【题解】
  • 虚幻引擎虚拟制片入门教程 之 Sequencer基础
  • 考研408--计算机网络--day1-概念组成功能三种交换技术分类
  • 网站标签怎么做跳转页面网站的建设ppt模板
  • Laravel下载和安装图解(非常详细)
  • Python机器学习---3.分类模型评估
  • Rust Tokio vs Go net/http:云原生与嵌入式生态选型指南
  • 【Java 详解】Mysql 索引从入门到精通
  • Vue收集表单数据
  • 正点原子RK3568学习日志10-向系统条件一个系统调用
  • 软件工程原则:构建高质量软件的基石
  • 哈尔滨在线制作网站网站3d展示怎么做
  • Python操作word实战
  • cms建站系统哪家好企业信息官网
  • 【Java EE进阶 --- SpringBoot】Mybatis - plus 操作数据库
  • ffmpeg下载和实战获取音视频时长
  • 如何高效批量修改多格式文本文件?
  • 移动测试利器Appium全方位解析:从原理、实战到应用场景
  • 018数据结构之队列——算法备赛
  • 开源 Linux 服务器与中间件(四)服务器--Tomcat