96SEO 2026-09-03 07:34 2
在分布式程序开发中。gRPC 作为 Google 开源的高性能 RPC 框架,凭借 Protobuf 二进制序列化的 gRPC 服务的最优选择之一。
使用者痛点:许多 Rust 开发者在建立 gRPC 时会碰到以下问题:

这篇文章从环境搭建入手。逐步展示如何解决这些痛点,并通过一个双向流式聊天示例完成全链路实现。
Tonic 依赖 Protobuf 编译器来解析 .proto 文件并生成 Rust 代码,不同程序的安装方式如下:
# Linux
sudo apt-get install protobuf-compiler
# macOS
brew install protobuf
# Windows
winget install -e --id Google.Protobuf
安装完成后执行 protoc --version 验证是否成功。
下面创建一个包含服务端和客户端的 Rust 项目,模拟真实的服务通信场景:
cargo new tonic-demo
cd tonic-demo
修改 Cargo.toml添加主要依赖和建立依赖:
# 二进制目标:服务端和客户端
]
name = "server"
path = "src/server.rs"
]
name = "client"
path = "src/client.rs"
tokio = { version = "1"。features = }
tonic = { version = "0.11",features = }
prost = "0.13"
prost-types = "0.13"
anyhow = "1"
chrono = { version = "0.4",features = }
tonic-build = "0.11"
anyhow = "1"
创建 build.rs 文件,用于在编译阶段自动生成对应的 Rust 代码:
use anyhow::Result;use std::path::Path;fn main -> Result<> {
// 告诉 Cargo 当 proto 文件变化时重新运行 build 脚本
println!,// 编译 proto 文件
tonic_build::configure
.build_server
.out_dir)
.compile?,Ok)
}
syntax = "proto3";package chat;// 聊天消息结构体
message ChatMessage {
string username = 1;// 使用者名
string content = 2;// 消息内容
string timestamp = 3;// 时间戳
}
// 双向流式 RPC 接口
service ChatService {
rpc ChatStream returns;}
Tonic 会在建立时把上面的 .proto 编译成对应模块。我们只需要在业务代码中通过以下方式引入:
pub mod chat {
说到tonic:,include_proto!,// 与 proto 包名保持一致
}
主要思路的观点是,利用 Tokio 的广播通道实现多客户端之间的消息分发;使用 Mutex 包装广播发送端,以保证并发安全。
use tokio::sync::{broadcast,Mutex};use tokio_stream::{wrappers::{BroadcastStream。ReceiverStream},StreamExt};其实,use tonic::{transport::Server。Request,Response,Status,Streaming};mod generated;pub use generated::chat::{
chat_service_server::{ChatService。ChatServiceServer},ChatMessage,};#
pub struct ChatServer {
broadcaster: Mutex
客户端负责两件事:读取键盘输入并发送、实时打印服务器广播。按理说,为避免阻塞,我们使用 Tokio 的任务并行处理。老实说,
use anyhow::Result;use chrono::Local;use futures_util::{SinkExt,StreamExt};use std::{io::{self。Write},sync::Arc};use tokio::{
再看io:,{AsyncBufReadExt。BufReader},sync::mpsc,};use tonic::{
transport::Channel。
Request,},mod generated;pub use generated::chat::{
chat_service_client::{ChatServiceClient}。ChatMessage,};#
async fn main -> Result<>{
// 建立连接
let channel =
Channel::from_static
.connect
.await?,let mut client =
ChatServiceClient::new;println,;io::
stdout
.flush?,let mut stdin_reader =
BufReader::
new(io::
stdin);let mut username=
String::
new;stdin_reader.
read_line.
await?,let username=
username.trim.
to_string;// 创建双向流请求通道
let (tx,rx)= mpsc::
channel;话说回来,let request=
Request::
new(ReceiverStream::
new);// 发起双向流 RPC 并获取响应流句柄
let mut response=
client.
chat_stream.
await?.
into_inner;// 启动任务持续打印服务器推送消息
tokio:的观点是,spawn(async move{
while
let Some)=
response.
next.
await{
println!(" {}: {}",msg.timestamp。msg.username,msg.content);}
eprintln,;}),// 主线程负责读取使用者输入并发送至服务器
loop{
print!,io::
stdout.
flush?,let mut line=
String::
new;stdin_reader.
read_line.
await?,按理说,if line.trim.
eq_ignore_ascii_case{
break;}
let msg=ChatMessage{
username:
username.clone。content:
line.trim.
to_string,timestamp:
Local:的观点是,now.
format.
to_string,};if tx.send.await.is_err{
eprintln!其实,(
"发送失败,可能服务器已关闭");break,}
}
Ok)
}
打开两个终端分别开启服务端和多个客户端进行交互验证:
# 开启服务端
cargo run --bin server
# 新终端启动多个客户端实例
cargo run --bin client
输入使用者名后即可发送聊天内容;所有在线客户端会实时收到对方消息,实现了基础的群聊功能。
使用者痛点:Tonic 原生没有统一的鉴权/日志框架,需要自行编写拦截器来统一处理。下面演示一个简易 Token 鉴权拦截器:
use tonic::{
service::{Interceptor}。Request,Status,};struct AuthInterceptor;说起来,impl Interceptor for AuthInterceptor {
fn call(&mut self。mut req: Request<'static>) ->
Result,Status>{
const EXPECTED:&'static str=
"Bearer tonic-demo-token";match req.metadata
.get
.and_n.ok){
Some if t == EXPECTED => {}
_ =>
return Err(Status::
unaunticated(
"Invalid token")),};Ok
}
}
// 在 Server 启动时注入拦截器:
Server ::builder
.layer(
tonic ::service ::
InterceptorLayer ::new)
.add_service)
.serve
.await?,
// 客户端请求前注入 Token:
let mut request= Request ::new);request.metadata_mut
.insert("authorization","Bearer tonic-demo-token".parse?),
TLS 加密传输
Pain point: 在生产环境直接使用明文 HTTP/2 会导致安全风险。不过,Tonic 基于 rustls 完全支持 TLS。只需提供证书和私钥就可以完成加密。
// 服务端 TLS 示例:
let cert= std ::fs ::
read?,let key= std ::fs ::
read?,
let identity= tonic ::transport ::
Identity ::from_pem;
let tls_config=
tonic ::transport ::
ServerTlsConfig ::
new
.identity;
Server ::builder
.tlsconfig?.addservice)
.serve
.await?,
// 客户端 TLS 示例:
let cacert= std ::fs ::
read?,let cacertificate=
tonic ::transport ::
Certificate ::
from_pem;说起来,
let tls=tonic ::
transport ::
ClientTlsConfig ::
new
.ca_certificate;
let channel=
Channel ::
// 注意这里仍然是 https scheme
.fromstatic
.tlsconfig?.connect
.await?,
四种 gRPC 方法对比
方法类型 描述
一元 RPC
客户端发送单次请求,服务端返回单次响应。适合查询类接口,如登录、获取配置信息。
服务端流式
一次请求对应多次响应。常用于日志拉取、文件下载等大数据返回场景。
客户端流式
多次请求合并为一次响应。适合批量上传、分块文件上传等。
双向流式
双方均可以随时发送消息,实现实时交互。典型场景包括即时聊天、行情推送、监控告警等。
}
Tonic 作为 Rust 环境中成熟且功能完整的 gRPC 框架。通过原生异步、类型安全还有丰富插件程序,降低了建立高性能分布式程序的门槛。如果你正在使用 Rust 开发微服务或需要可靠的跨语言 RPC 通信。请把 Tonic 纳入技术栈,并结合这篇文章提供的常用方法快速落地生产级别服务。
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback