0Pricing
Learn Rust Coding · Lección

Implementar un servidor gRPC

Ofrezca métodos RPC unarios

Implementar un servidor gRPC es una lección gratuita de Learn Rust Coding en CoddyKit. Esta es la lección 3 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Learn Rust Coding, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Learn Rust Coding incluye 4 lecciones en total.

El trait de servidor generado

Para un servicio llamado Greeter, tonic genera un trait en greeter_server. Debe implementarlo en su propia estructura para proporcionar el comportamiento.

El trait es async mediante #[tonic::async_trait], por lo que cada método es un async fn que devuelve un Result.

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

Wrappers de solicitud y respuesta

Los métodos reciben un tonic::Request<T> y devuelven un tonic::Response<T>. Estos wrappers contienen metadatos, extensiones y el mensaje interno.

Llame a .into_inner() para obtener el mensaje decodificado y a Response::new(..) para construir una respuesta.

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

Una estructura de servidor

Defina una estructura para contener cualquier estado compartido, como un pool de conexiones a la base de datos. A menudo deriva Default cuando no tiene estado.

Implementará el trait generado en esta estructura.

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

Implementar un método unario

Anote el bloque impl con #[tonic::async_trait] e implemente cada rpc como un async fn que coincida con la firma generada.

Devuelva Ok(Response::new(reply)) cuando la operación tenga éxito.

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

Devolver errores con Status

Los errores se devuelven como tonic::Status, que se asigna a un código de estado de gRPC. Use constructores como Status::invalid_argument o Status::not_found.

La cadena del mensaje se envía al cliente junto con el código.

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

Compilar y servir

Use tonic::transport::Server en un main asíncrono. Añada su servicio envuelto en su tipo ...Server generado y, después, llame a serve con una dirección de socket.

La macro #[tokio::main] proporciona el 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(())
}

Respuestas en streaming del servidor

Un método con streaming del servidor devuelve un tipo de stream. tonic utiliza un tipo asociado y un stream en boxing; un canal mpsc es una forma habitual de suministrar mensajes.

Devuelve un ReceiverStream envuelto en un 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)))

Leer metadatos

Los metadatos de la solicitud contienen encabezados, como los tokens de autenticación. Acceda a ellos con request.metadata() antes de consumir el cuerpo.

Las claves son ASCII y no distinguen entre mayúsculas y minúsculas; los valores se devuelven como MetadataValue.

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

Interceptores

Un interceptor se ejecuta antes de cada solicitud, por lo que resulta ideal para autenticación o registro. Recibe el Request y devuelve esta o un error Status.

Asócielo con with_interceptor al añadir el servicio.

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

Apagado ordenado

Use serve_with_shutdown para dejar de aceptar conexiones cuando se resuelva un future, como una señal de Ctrl-C.

Las solicitudes en curso terminan antes de que el servidor salga, lo que evita cierres abruptos.

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

Estado compartido

Para compartir estado mutable entre solicitudes, guárdelo detrás de Arc y de una primitiva de sincronización como tokio::sync::Mutex dentro de su estructura de servidor.

tonic clona el servicio para cada conexión, por lo que el patrón adecuado consiste en usar handles compartidos baratos de clonar.

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

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

Comprobación rápida

¿Cómo informan los métodos gRPC de los fallos en tonic?

Resumen

Ha implementado el trait de servidor generado: desempaquetar solicitudes, devolver respuestas y errores Status, servir con tokio, transmitir respuestas, leer metadatos, añadir interceptores, realizar un apagado ordenado y compartir el estado mediante Arc.

A continuación creará un cliente para llamar a este servidor.

Preguntas frecuentes

¿La lección «Implementar un servidor gRPC» es gratis?

Sí — el texto completo de «Implementar un servidor gRPC» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Learn Rust Coding, actualiza a CoddyKit PRO. El curso de Learn Rust Coding incluye 4 lecciones en total.

¿Qué aprenderé en «Implementar un servidor gRPC»?

Ofrezca métodos RPC unarios Practicas Learn Rust Coding con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Learn Rust Coding?

No se requiere experiencia previa. Learn Rust Coding en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 3 de 4.

¿Cuánto tiempo toma la lección «Implementar un servidor gRPC»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Learn Rust Coding?

Sí. Cada lección de Learn Rust Coding incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Protobuf y definiciones de servicios
  2. Generar código con tonic-build
  3. Implementar un servidor gRPC
  4. Realizar llamadas desde un cliente gRPC
← Volver a Learn Rust Coding