十九、Rust Tcp Rpc 示例

  前一篇,我们演示了 rust grpc 的应用,但 grpc 是基于 http 的,按理说其协议更重,同时也确见到网友验证过,相比 http 的 rpc,tpc 下的 rpc 性能确实更有优势。

  同时,不同于 grpc 要编写一份 “中间文件” (protobuf 文件),tcp rpc 可以认为是 直接 rust 到 rust 的编程,没有 “中间文件” 的编写,编写期代码提示,语法校验,都是原生的。因此,本篇也进行一个 tcp rpc 的演示。

  • Tcp rpc 的劣势也较明显,跨语言调用能力较弱,纯 rust 体系会更适用。

Tcp 版 rpc 方案不多,本例直接使用 tarpc

  • Tarpc - https://github.com/google/tarpc,3k Star、940 Commits、2024-03 updated。
  • Tarpc 的编解码库为 bincode-org/bincode,据说性能极高。
  • 己知使用 tarpc 的项目有 solana。(Solana 同时使用了 tonic 及 tarpc)

目录结构

.
├── Cargo.toml
├── README.md
└── src├── client.rs├── lib.rs└── server.rs

创建项目

  • 创建一个 lib 项目:
cargo new tarpc --lib
  • Cargo.toml
[package]
name = "tarpc"
version = "0.1.0"
edition = "2021"
description = "An example server built on tarpc."[dependencies]
anyhow = "1.0"
futures = "0.3"
tarpc = { version = "0.34", features = ["full"] }
tokio = { version = "1", features = ["macros", "net", "rt-multi-thread"] }
clap = { version = "4.4.18", features = ["derive"] }  # 与 rpc 无关, 仅演示、从命令行读取参数[lib]
name = "service"
path = "src/lib.rs"[[bin]]
name = "tarpc_server"
path = "src/server.rs"[[bin]]
name = "tarpc_client"
path = "src/client.rs"

定义服务

  • tarpc/src/lib.rs
#[tarpc::service]
pub trait Hello {async fn hello(name: String) -> String;
}

服务实现

  • tarpc/src/server.rs
use std::net::{IpAddr, Ipv6Addr, SocketAddr};use futures::{future, prelude::*};
use tarpc::{context, server::{self, Channel, incoming::Incoming}, tokio_serde::formats::Json};use service::Hello;#[derive(Clone)]
struct HelloServer(SocketAddr);impl Hello for HelloServer {async fn hello(self, _: context::Context, name: String) -> String {format!("Hello, {name}! You are connected from {}", self.0)}
}#[tokio::main]
async fn main() -> anyhow::Result<()> {async fn spawn(fut: impl Future<Output=()> + Send + 'static) { tokio::spawn(fut); }let server_addr = (IpAddr::V6(Ipv6Addr::LOCALHOST), 50051); // IpAddr::from([0, 0, 0, 0])let mut listener = tarpc::serde_transport::tcp::listen(&server_addr, Json::default).await?;listener.config_mut().max_frame_length(usize::MAX);listener.filter_map(|r| future::ready(r.ok()))      // Ignore accept errors..map(server::BaseChannel::with_defaults).max_channels_per_key(1, |t| t.transport().peer_addr().unwrap().ip()) // Limit channels to 1 per IP..map(|channel| {let server = HelloServer(channel.transport().peer_addr().unwrap());channel.execute(server.serve()).for_each(spawn)}).buffer_unordered(10)       // Max 10 channels..for_each(|_| async {}).await;Ok(())
}

调用实现

  • tarpc/src/client.rs
use std::net::SocketAddr;
use tarpc::{client, context, tokio_serde::formats::Json};
use service::HelloClient; // 由#[tarpc::service]提供#[tokio::main]
async fn main() -> anyhow::Result<()> {let mut transport = tarpc::serde_transport::tcp::connect("[::1]:50051", Json::default);transport.config_mut().max_frame_length(usize::MAX);let client = HelloClient::new(client::Config::default(), transport.await?).spawn();match client.hello(context::current(), format!("{}1", "Bob")).await {Ok(hello) => println!("{:?}", hello),Err(e) => panic!("{:?}", anyhow::Error::from(e)),}Ok(())
}
  • HelloClient 是由 #[tarpc::service]pub trait Hello 提供的生成,直接引用就可以了。
    • 如遇 CLion IDE 对此引用 “漂红”,可尝试 JetBrains 新发布的 RustRover IDE,或使用 VScode + rust-analyzer 。

运行/测试

cargo run --bin tarpc_server
cargo run --bin tarpc_client

关于lib.rs共享

  1. 可以在各项目间直接复制,犹如 grpc 的 proto 一样;
  2. 可以建设私有 crates 仓库,并将服务定义的项目发布上去;
  3. 可以直接依赖 git 如:xxx = { git = "http://github.com/xxx", branch = "master" }

  完事~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/794136.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

系统分析师-综合知识-应用数学与经济管理

系统分析师-综合知识-应用数学与经济管理 更多软考资料 https://ruankao.blog.csdn.net/ 文章目录 系统分析师-综合知识-应用数学与经济管理概述最小生成树真题-给出图真题-给出表 最短路径关键路径关键路径基本关键路径升级 网络与最大流量指派问题最小解最大解 线性规划决策…

软考--软件设计师(软件工程总结2)

目录 1.测试方法 2.软件项目管理 3.软件容错技术 4.软件复杂性度量 5.结构化分析方法&#xff08;一种面向数据流的开发方法&#xff09; 6.数据流图 1.测试方法 软件测试&#xff1a;静态测试&#xff08;被测程序采用人工检测&#xff0c;计算机辅助静态分析的手段&…

虚拟机打不开

问题 另一个程序已锁定文件的一部分&#xff0c;进程无法访问 打不开磁盘“G:\centeros\hadoop104kl\hadoop100-cl2.vmdk”或它所依赖的某个快照磁盘。 模块“Disk”启动失败。 未能启动虚拟机。 原因 前一次非正常关闭虚拟机导致.lck 文件是VMWare软件的一种磁盘锁文件&…

蓝桥杯算法题:外卖店优先级

“饱了么”外卖系统中维护着 N 家外卖店&#xff0c;编号 1∼N。每家外卖店都有一个优先级&#xff0c;初始时 (0时刻) 优先级都为 0。每经过 1个时间单位&#xff0c;如果外卖店没有订单&#xff0c;则优先级会减少 1&#xff0c;最低减到 0&#xff1b;而如果外卖店有订单&am…

特定领域软件体系结构

1.DSSA的定义 简单地说&#xff0c;DSSA&#xff08;Domain Specific Software Architecture&#xff09;就是在一个特定应用领域中为一组应用提供组织结构参考的标准软件体系结构。 从功能覆盖的范围的角度有两种理解DSSA中领域的含义的方式&#xff1a; &#xff08;1&#x…

使用Python写简单的点云高斯滤波

一、代码 Python import numpy as np import open3d as o3ddef apply_gaussian_filter(pcd, k=30, sigma=1.0):"""对点云应用高斯滤波。参数:pcd (open3d.geometry.PointCloud): 输入的点云。k (int): 每个点的邻居数量。sigma (float): 高斯核的标准差。返回…

极海APM32电机驱动板记录(二)

文章目录 1、解除写保护2、极海驱动板资源概述3、新建工程4、点灯5、嘀嗒定时器6、中断7、串口打印8、adc读取9、i2c尝试10、定时器测试11、电机驱动pwm测试 上一篇文章算是简单了解了一下极海的板子开发环境吧&#xff0c;结果前几天板子来了&#xff0c;然后发现一个大bug&am…

12、高精度加法(含源码)

高精度加法 难度&#xff1a;简单 题目描述 给定两个正整数&#xff0c;计算它们的和 输入格式 共两行&#xff0c;每行包含一个整数。 输出格式 共一行&#xff0c;包含所求的和。 数据范围&#xff1a; 1≤整数长度≤100000输入样例&#xff1a; 12 23输出样例&…

继承 多态 接口 抽象

继承&#xff1a; 继承需要我们学习的点&#xff1a; 什么是继承&#xff0c;继承的好处继承的特点子类到底能继承父类的那些内容&#xff1f;继承中&#xff1a;成员变量的访问特点继承中&#xff1a;成员方法的访问特点继承中&#xff1a;构造方法的特点This,super使用总结…

2024.3.15力扣每日一题——卖木头块

2024.3.15 题目来源我的题解方法一 记忆化搜索&#xff08;自顶向下&#xff09;方法二 动态规划&#xff08;自底向上&#xff09; 题目来源 力扣每日一题&#xff1b;题序&#xff1a;2312 我的题解 方法一 记忆化搜索&#xff08;自顶向下&#xff09; 用 f(x,y)表示当木…

firefox切换本地服务和全球服务的方法

方法1&#xff1a;“设置”>“同步">“切换全球/本地服务器” https://jingyan.baidu.com/article/1974b2898523bbb5b1f774e2.html 方法2&#xff1a;地址栏输入about:config&#xff0c;搜索首选项名称里输入identity.fxaccounts.autoconfig.uri&#xff0c;填入…

Docker Desktop 不支持 host 网络模式

先把这个结论的放在前面&#xff0c;直接访问链接就能看到官方文档中已经明确说了不支持。 参考链接&#xff1a;docker desktop for windows 不支持 host 网络模式 以前对于 docker 的网络模式&#xff0c;一直只是了解&#xff0c;没有亲自尝试过。结果今天在尝试 docker 的 …

react 父子组件的渲染机制 | 优化手段

文章目录 父子组件的渲染机制优化手段与实践写法父组件&#xff1a;下发stateprops.children 传递无状态组件props传递组件 React.memo缓存子组件与useCallback结合 父子组件的渲染机制 渲染分初次渲染和重新渲染 React组件会在两种情况下发生重新渲染 当组件自身的state发生…

如何同时安全高效管理多个谷歌账号?

您的业务活动需要多个 Gmail 帐户吗&#xff1f;出海畅游&#xff0c;Gmail账号是少不了的工具之一&#xff0c;可以关联到Twitter、Facebook、Youtube、Chatgpt等等平台&#xff0c;可以说是海外网络的“万能锁”。但是大家都知道&#xff0c;以上这些平台注册多账号如果产生关…

蓝桥集训之垒骰子

蓝桥集训之垒骰子 核心思想&#xff1a;矩阵乘法 f[i]存顶面数值 构造a矩阵 使得*f[i] f[i-1]a 则f[i] f[1] * an 快速幂优化 #include <iostream>#include <cstring>#include <algorithm>using namespace std;typedef long long LL;const int N 6,m…

Oracle APEX 23.2版本 使用应用程序工作副本进行协作开发

现状描述&#xff1a; 当前APEX协作开发都是在同一应用程序下进行的&#xff0c;这样做有可能因同一时间对同一数据进行操作造成锁表或其他问题&#xff0c;Oracle APEX23.2版本迭代后新增了部分功能&#xff0c;可以创建应用程序的工作副本来修复错误、添加功能&#xff0c;然…

C++ setmap

&#x1f493;博主CSDN主页:麻辣韭菜&#x1f493;   ⏩专栏分类&#xff1a;C知识分享⏪   &#x1f69a;代码仓库:C高阶&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学习更多C知识   &#x1f51d;&#x1f51d; 目录 前言 一.树形结构的关联式容器 &#x…

移动开发技术历史演化简介h5,跨平台,原生的各种技术实现方案的简单介绍

移动端的开发技术是指针对移动设备如智能手机和平板电脑等便携终端进行应用程序和服务创建的过程。本文将主要介绍一下移动端的开发技术的历史进化历程。讲述h5&#xff0c;跨平台&#xff0c;原生的各种技术实现方案和他们各自的优势与不足。 移动开发&#xff0c;不仅是编程技…

在Ubuntu系统下连接远程Ubuntu服务器

本篇文章介绍&#xff0c;如何在Ubuntu系统下连接远程Ubuntu系统并传输文件。 一. 连接远程Ubuntu服务器。 1. 打开命令行&#xff0c;输入 : sudo apt-get update &#xff0c; 对系统进行更新。 2. 安装 OpenSSH Server&#xff0c;输入 &#xff1a; sudo apt-get insta…

聊一聊电子邮件?

电子邮件是什么&#xff1f; 电子邮件是一种基于客户/服务器架构的应用。功能是实现人与人之间的交流。直到现在&#xff0c;电子邮件依然是当前因特网 注意&#xff1a;基于客户/服务器方式和基于B/S架构不一样&#xff01;客户/服务器表示的范围更广&#xff0c;当基于客户…