0Pricing
Learn Rust Coding · Lekcja

Implementowanie serwera gRPC

Udostępni Pan/Pani metody RPC typu unary.

Implementowanie serwera gRPC to bezpłatna lekcja Learn Rust Coding na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Learn Rust Coding, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Learn Rust Coding zawiera 4 lekcji w sumie.

Wygenerowana cecha serwera

Dla usługi o nazwie Greeter tonic generuje cechę w module greeter_server. Implementujesz ją dla własnej struktury, aby określić jej działanie.

Cecha jest asynchroniczna dzięki #[tonic::async_trait], dlatego każda metoda jest funkcją async zwracającą Result.

use greeter::v1::greeter_server::{Greeter, GreeterServer};
use greeter::v1::{HelloRequest, HelloReply};

Opakowania żądań i odpowiedzi

Metody przyjmują tonic::Request<T> i zwracają tonic::Response<T>. Te opakowania zawierają metadane, rozszerzenia oraz wewnętrzny komunikat.

Wywołaj .into_inner(), aby uzyskać zdekodowany komunikat, a następnie użyj Response::new(..), aby utworzyć odpowiedź.

let req: HelloRequest = request.into_inner();
let reply = HelloReply { message: format!("Hi {}", req.name) };
Ok(Response::new(reply))

Struktura serwera

Zdefiniuj strukturę przechowującą współdzielony stan, na przykład pulę połączeń z bazą danych. Jeśli serwer nie ma stanu, często implementuje się dla niej Default.

Wygenerowaną cechę zaimplementujesz dla tej struktury.

#[derive(Default)]
pub struct MyGreeter {}

Implementowanie metody unarnej

Oznacz blok impl za pomocą #[tonic::async_trait] i zaimplementuj każdą procedurę rpc jako funkcję async zgodną z wygenerowaną sygnaturą.

W przypadku powodzenia zwróć Ok(Response::new(reply)).

#[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}") }))
    }
}

Zwracanie błędów za pomocą Status

Błędy są zwracane jako tonic::Status, które odwzorowuje kod stanu gRPC. Używaj konstruktorów takich jak Status::invalid_argument lub Status::not_found.

Tekst komunikatu jest wysyłany do klienta razem z kodem.

if name.is_empty() {
    return Err(Status::invalid_argument("name must not be empty"));
}

Budowanie i uruchamianie serwera

Użyj tonic::transport::Server w asynchronicznej funkcji main. Dodaj usługę opakowaną w wygenerowany typ ...Server, a następnie wywołaj serve, przekazując adres gniazda.

Makro #[tokio::main] udostępnia środowisko wykonawcze.

#[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(())
}

Odpowiedzi strumieniowane przez serwer

Metoda strumieniowana przez serwer zwraca typ strumienia. tonic używa powiązanego typu oraz strumienia opakowanego w pudełko, a kanał mpsc jest często używany do dostarczania komunikatów.

Zwracasz ReceiverStream opakowany w 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)))

Odczytywanie metadanych

Metadane żądania zawierają nagłówki, takie jak tokeny uwierzytelniania. Uzyskaj do nich dostęp za pomocą request.metadata() przed pobraniem treści.

Klucze są zapisane w ASCII i nie rozróżniają wielkości liter, a wartości są zwracane jako MetadataValue.

if let Some(token) = request.metadata().get("authorization") {
    // validate token
} else {
    return Err(Status::unauthenticated("missing token"));
}

Interceptory

Interceptor jest uruchamiany przed każdym żądaniem, dlatego idealnie nadaje się do uwierzytelniania lub rejestrowania. Otrzymuje Request i zwraca je albo błąd Status.

Dołącz go za pomocą with_interceptor podczas dodawania usługi.

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))

Kontrolowane wyłączanie

Użyj serve_with_shutdown, aby przestać przyjmować połączenia po zakończeniu działania future, na przykład po odebraniu sygnału Ctrl-C.

Żądania będące w toku zostaną ukończone przed wyłączeniem serwera, co zapobiega ich nagłemu przerwaniu.

Server::builder()
    .add_service(GreeterServer::new(MyGreeter::default()))
    .serve_with_shutdown(addr, async {
        tokio::signal::ctrl_c().await.ok();
    })
    .await?;

Współdzielony stan

Aby współdzielić zmienny stan między żądaniami, przechowuj go za Arc oraz mechanizmem synchronizacji, takim jak tokio::sync::Mutex, wewnątrz struktury serwera.

tonic klonuje usługę dla każdego połączenia, dlatego właściwym wzorcem są tanie w klonowaniu współdzielone uchwyty.

use std::sync::Arc;
use tokio::sync::Mutex;

#[derive(Default)]
pub struct MyGreeter {
    hits: Arc<Mutex<u64>>,
}

Szybkie sprawdzenie

W jaki sposób metody gRPC zgłaszają błędy w tonic?

Podsumowanie

Zaimplementowałeś wygenerowaną cechę serwera: rozpakowywanie żądań, zwracanie odpowiedzi i błędów Status, uruchamianie serwera za pomocą tokio, strumieniowanie odpowiedzi, odczytywanie metadanych, dodawanie interceptorów, kontrolowane wyłączanie oraz współdzielenie stanu przez Arc.

Teraz utworzysz klienta wywołującego ten serwer.

Często zadawane pytania

Czy lekcja „Implementowanie serwera gRPC” jest bezpłatna?

Tak — pełny tekst „Implementowanie serwera gRPC” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Learn Rust Coding, przejdź na CoddyKit PRO. Kurs Learn Rust Coding zawiera 4 lekcji w sumie.

Co nauczysz się w „Implementowanie serwera gRPC”?

Udostępni Pan/Pani metody RPC typu unary. Ćwiczysz Learn Rust Coding z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Learn Rust Coding?

Nie wymagamy żadnego doświadczenia. Learn Rust Coding w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.

Ile czasu zajmuje lekcja „Implementowanie serwera gRPC”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Learn Rust Coding?

Tak. Każda lekcja Learn Rust Coding zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Protobuf i definicje usług
  2. Generowanie kodu za pomocą tonic-build
  3. Implementowanie serwera gRPC
  4. Wywoływanie z klienta gRPC
← Powrót do Learn Rust Coding