0Pricing
Learn Rust Coding · Урок

Реализация сервера 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 — локальная установка не требуется.

Все уроки этого курса

  1. Protobuf и определения сервисов
  2. Генерация кода с tonic-build
  3. Реализация сервера gRPC
  4. Вызовы из клиента gRPC
← Назад к Learn Rust Coding