Реализация сервера gRPC
Предоставляйте унарные методы RPC.
«Реализация сервера gRPC» — бесплатный урок Learn Rust Coding на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Learn Rust Coding, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Learn Rust Coding содержит 4 уроков всего.
Части этого урока еще не переведены и отображаются на английском.
The Generated Server Trait
For a service named Greeter, tonic generates a trait in greeter_server. You implement it on your own struct to provide behavior.
The trait is async via #[tonic::async_trait], so each method is an async fn returning a Result.
use greeter::v1::greeter_server::{Greeter, GreeterServer};
use greeter::v1::{HelloRequest, HelloReply};Request and Response Wrappers
Methods take a tonic::Request<T> and return a tonic::Response<T>. These wrappers carry metadata, extensions, and the inner message.
Call .into_inner() to get the decoded message, and Response::new(..) to build a reply.
let req: HelloRequest = request.into_inner();
let reply = HelloReply { message: format!("Hi {}", req.name) };
Ok(Response::new(reply))A Server Struct
Define a struct to hold any shared state, like a database pool. Often it derives Default when stateless.
You will implement the generated trait on this struct.
#[derive(Default)]
pub struct MyGreeter {}Implementing a Unary Method
Annotate the impl block with #[tonic::async_trait] and implement each rpc as an async fn matching the generated signature.
Return Ok(Response::new(reply)) on success.
#[tonic::async_trait]
impl Greeter for MyGreeter {
async fn say_hello(&self, request: Request<HelloRequest>)
-> Result<Response<HelloReply>, Status> {
let name = request.into_inner().name;
Ok(Response::new(HelloReply { message: format!("Hello {name}") }))
}
}Returning Errors with Status
Errors are returned as tonic::Status, which maps to a gRPC status code. Use constructors like Status::invalid_argument or Status::not_found.
The message string is sent to the client alongside the code.
if name.is_empty() {
return Err(Status::invalid_argument("name must not be empty"));
}Building and Serving
Use tonic::transport::Server in an async main. Add your service wrapped in its generated ...Server type, then call serve with a socket address.
The #[tokio::main] macro provides the runtime.
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let addr = "[::1]:50051".parse()?;
Server::builder()
.add_service(GreeterServer::new(MyGreeter::default()))
.serve(addr)
.await?;
Ok(())
}Server Streaming Responses
A server-streaming method returns a stream type. tonic uses an associated type plus a boxed stream; an mpsc channel is a common way to feed messages.
You return a ReceiverStream wrapped in a Response.
use tokio_stream::wrappers::ReceiverStream;
let (tx, rx) = tokio::sync::mpsc::channel(8);
tokio::spawn(async move { tx.send(Ok(reply)).await.ok(); });
Ok(Response::new(ReceiverStream::new(rx)))Reading Metadata
Request metadata holds headers like auth tokens. Access it with request.metadata() before consuming the body.
Keys are ASCII and case-insensitive; values are returned as MetadataValue.
if let Some(token) = request.metadata().get("authorization") {
// validate token
} else {
return Err(Status::unauthenticated("missing token"));
}Interceptors
An interceptor runs before each request, ideal for auth or logging. It receives the Request and returns it or a Status error.
Attach it with with_interceptor when adding the service.
fn auth(req: Request<()>) -> Result<Request<()>, Status> {
match req.metadata().get("authorization") {
Some(_) => Ok(req),
None => Err(Status::unauthenticated("no token")),
}
}
// .add_service(GreeterServer::with_interceptor(svc, auth))Graceful Shutdown
Use serve_with_shutdown to stop accepting connections when a future resolves, such as a Ctrl-C signal.
In-flight requests finish before the server exits, avoiding abrupt drops.
Server::builder()
.add_service(GreeterServer::new(MyGreeter::default()))
.serve_with_shutdown(addr, async {
tokio::signal::ctrl_c().await.ok();
})
.await?;Shared State
To share mutable state across requests, store it behind Arc and a synchronization primitive like tokio::sync::Mutex inside your server struct.
tonic clones the service per connection, so cheap-to-clone shared handles are the right pattern.
use std::sync::Arc;
use tokio::sync::Mutex;
#[derive(Default)]
pub struct MyGreeter {
hits: Arc<Mutex<u64>>,
}Quick Check
How do gRPC methods report failures in tonic?
Recap
You implemented the generated server trait: unwrapping requests, returning responses and Status errors, serving with tokio, streaming responses, reading metadata, adding interceptors, graceful shutdown, and sharing state via Arc.
Next you will build a client to call this server.
Часто задаваемые вопросы
Урок «Реализация сервера gRPC» бесплатный?
Да — полный текст урока «Реализация сервера gRPC» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Learn Rust Coding, подпишись на CoddyKit PRO. Курс Learn Rust Coding содержит 4 уроков всего.
Чему я научусь в уроке «Реализация сервера gRPC»?
Предоставляйте унарные методы RPC. Ты практикуешь Learn Rust Coding с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Learn Rust Coding?
Предыдущий опыт не требуется. Learn Rust Coding на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «Реализация сервера gRPC»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Learn Rust Coding?
Да. Каждый урок Learn Rust Coding включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Protobuf и определения сервисов
- Генерация кода с tonic-build
- Реализация сервера gRPC
- Вызовы из клиента gRPC