0Pricing
C# Academy · Lección

RPC unarios y streaming del servidor

Implemente llamadas unarias y streaming del lado del servidor para enviar datos del servidor al cliente en tiempo real.

RPC unarios y streaming del servidor es una lección gratuita de C# Academy en CoddyKit. Esta es la lección 2 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 C# Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de C# Academy incluye 4 lecciones en total.

Tipos de RPC de gRPC

gRPC admite cuatro patrones de RPC: Unary (solicitud/respuesta), Server Streaming (el cliente envía una solicitud y el servidor envía muchas respuestas), Client Streaming y Bidirectional Streaming. Esta lección cubre los dos primeros.

RPC Unary: el patrón básico

Unary es el patrón más sencillo: una solicitud y una respuesta. Parece una llamada a una función normal, pero se transmite mediante HTTP/2 con codificación Protobuf.

// .proto definition
service OrderService {
  rpc GetOrder (GetOrderRequest) returns (OrderResponse);
}

message GetOrderRequest { int32 id = 1; }
message OrderResponse   { int32 id = 1; string status = 2; double total = 3; }

Implementación de un RPC Unary

Sobrescriba el método base generado. ServerCallContext proporciona metadatos, token de cancelación, plazo e información del par.

public class OrderService : OrderService.OrderServiceBase
{
    private readonly IOrderRepository _repo;
    public OrderService(IOrderRepository repo) => _repo = repo;

    public override async Task<OrderResponse> GetOrder(
        GetOrderRequest request,
        ServerCallContext context)
    {
        var order = await _repo.GetByIdAsync(request.Id, context.CancellationToken);
        if (order is null)
            throw new RpcException(new Status(StatusCode.NotFound, "Order not found"));

        return new OrderResponse
        {
            Id     = order.Id,
            Status = order.Status.ToString(),
            Total  = (double)order.Total
        };
    }
}

Llamar a una RPC unaria desde un cliente

El cliente generado proporciona métodos de apariencia síncrona y métodos verdaderamente asíncronos. Utilice siempre la variante Async en producción.

var client = new OrderService.OrderServiceClient(channel);

// Async call with cancellation
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5));
var reply = await client.GetOrderAsync(
    new GetOrderRequest { Id = 42 },
    cancellationToken: cts.Token);

Console.WriteLine($"Order {reply.Id}: {reply.Status} - ${reply.Total}");

Streaming del servidor: definición de proto

El streaming del servidor añade la palabra clave stream antes del tipo de respuesta. El servidor envía varios mensajes a través de la misma conexión antes de cerrar el stream.

service StockService {
  // Client sends one symbol, server streams price updates
  rpc WatchStock (WatchRequest) returns (stream StockUpdate);
}

message WatchRequest  { string symbol = 1; }
message StockUpdate   { string symbol = 1; double price = 2; int64 timestamp = 3; }

Implementar el streaming del servidor

Utilice IServerStreamWriter<T> para enviar mensajes. El método devuelve un Task: escriba hasta terminar y luego devuelva el control.

public override async Task WatchStock(
    WatchRequest request,
    IServerStreamWriter<StockUpdate> responseStream,
    ServerCallContext context)
{
    while (!context.CancellationToken.IsCancellationRequested)
    {
        var price = await _market.GetPriceAsync(request.Symbol);

        await responseStream.WriteAsync(new StockUpdate
        {
            Symbol    = request.Symbol,
            Price     = price,
            Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
        });

        await Task.Delay(1000, context.CancellationToken);
    }
}

Consumir un stream del servidor desde el cliente

Utilice await foreach sobre ResponseStream.ReadAllAsync() para procesar cada mensaje a medida que llega.

using var call = client.WatchStock(
    new WatchRequest { Symbol = "MSFT" });

await foreach (var update in call.ResponseStream.ReadAllAsync())
{
    Console.WriteLine($"{update.Symbol}: ${update.Price:F2}");
}
// Continues until server closes the stream or client cancels

Cancelar un stream del servidor

Pase un CancellationToken al abrir la llamada para detener el stream desde el cliente. El servidor recibe la cancelación a través de su propio token.

var cts = new CancellationTokenSource();

// Cancel after 30 seconds
cts.CancelAfter(TimeSpan.FromSeconds(30));

using var call = client.WatchStock(
    new WatchRequest { Symbol = "AAPL" },
    cancellationToken: cts.Token);

try
{
    await foreach (var update in
        call.ResponseStream.ReadAllAsync(cts.Token))
    {
        Console.WriteLine($"Price: {update.Price}");
    }
}
catch (OperationCanceledException)
{
    Console.WriteLine("Stream cancelled.");
}

Metadatos: encabezados y tráileres de solicitud

gRPC admite metadatos (pares clave-valor) enviados como encabezados antes de la respuesta y como tráileres después de la respuesta. Utilícelos para tokens de autenticación, ID de trazabilidad o cursores de paginación.

// Server: send initial metadata
await context.WriteResponseHeadersAsync(new Metadata
{
    { "x-correlation-id", Guid.NewGuid().ToString() }
});

// Server: set trailing metadata
context.ResponseTrailers.Add("x-total-count", "1500");

// Client: read headers
var headers  = await call.ResponseHeadersAsync;
var trailerId = headers.GetValue("x-correlation-id");

gRPC-Web para clientes de navegador

Los navegadores no pueden utilizar gRPC sin modificaciones (no admiten los tráileres de HTTP/2). Utilice Grpc.AspNetCore.Web y el cliente JavaScript grpc-web, o Grpc.Net.Client.Web de Blazor.

// dotnet add package Grpc.AspNetCore.Web

app.UseGrpcWeb();
app.MapGrpcService<GreeterService>().EnableGrpcWeb();

// Blazor client:
var handler = new GrpcWebHandler(GrpcWebMode.GrpcWeb,
    new HttpClientHandler());
using var channel = GrpcChannel.ForAddress(
    "https://localhost:7042",
    new GrpcChannelOptions { HttpHandler = handler });

Caso real: servicio de streaming de registros

Un servicio de agregación de registros transmite en tiempo real las entradas de registro de las aplicaciones a los clientes de supervisión conectados mediante streaming del servidor.

public override async Task StreamLogs(
    LogStreamRequest request,
    IServerStreamWriter<LogEntry> responseStream,
    ServerCallContext context)
{
    await foreach (var log in _logChannel.Reader.ReadAllAsync(
        context.CancellationToken))
    {
        if (log.Level >= request.MinLevel)
        {
            await responseStream.WriteAsync(new LogEntry
            {
                Level   = log.Level.ToString(),
                Message = log.Message,
                Timestamp = Timestamp.FromDateTime(log.Timestamp)
            });
        }
    }
}

Comprobación rápida

¿Qué palabra clave en un archivo .proto indica una RPC con streaming del servidor?

Resumen: RPC unarias y con streaming del servidor

Ideas clave:

  • RPC unaria: una solicitud y una respuesta; es el patrón más común
  • Streaming del servidor: una solicitud y varios mensajes de respuesta a lo largo del tiempo
  • Implemente el streaming del servidor escribiendo en IServerStreamWriter<T>
  • Consuma los streams del servidor con await foreach sobre ReadAllAsync()
  • Utilice CancellationToken para detener los streams correctamente desde cualquiera de los dos lados
  • gRPC-Web permite que los clientes de navegador llamen a servicios gRPC

Preguntas frecuentes

¿La lección «RPC unarios y streaming del servidor» es gratis?

Sí — el texto completo de «RPC unarios y streaming del servidor» 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 C# Academy, actualiza a CoddyKit PRO. El curso de C# Academy incluye 4 lecciones en total.

¿Qué aprenderé en «RPC unarios y streaming del servidor»?

Implemente llamadas unarias y streaming del lado del servidor para enviar datos del servidor al cliente en tiempo real. Practicas C# Academy 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 C# Academy?

No se requiere experiencia previa. C# Academy 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 2 de 4.

¿Cuánto tiempo toma la lección «RPC unarios y streaming del servidor»?

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 C# Academy?

Sí. Cada lección de C# Academy 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. Fundamentos de gRPC y Protobuf
  2. RPC unarios y streaming del servidor
  3. Streaming del cliente y bidireccional
  4. Plazos, cancelación e interceptores
← Volver a C# Academy