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
- Protobuf i definicje usług
- Generowanie kodu za pomocą tonic-build
- Implementowanie serwera gRPC
- Wywoływanie z klienta gRPC