0Pricing
C# Academy · Lezione

RPC unarie e streaming dal server

Implementi chiamate unarie e streaming dal server per inviare dati in tempo reale dal server al client.

RPC unarie e streaming dal server è una lezione C# Academy gratuita su CoddyKit. Questa è la lezione 2 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento C# Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso C# Academy include 4 lezioni in totale.

Tipi di RPC gRPC

gRPC supporta quattro modelli RPC: Unary (richiesta/risposta), Server Streaming (il client ne invia una, il server ne invia molte), Client Streaming e Bidirectional Streaming. Questa lezione tratta i primi due.

RPC Unary: il modello di base

Unary è il modello più semplice: una richiesta e una risposta. Sembra una normale chiamata di funzione, ma viaggia su HTTP/2 con codifica 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; }

Implementare un RPC Unary

Sovrascriva il metodo di base generato. ServerCallContext fornisce metadati, token di annullamento, scadenza e informazioni sul peer.

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
        };
    }
}

Chiamare una RPC unaria da un client

Il client generato offre metodi dall'aspetto sincrono e metodi realmente asincroni. In produzione utilizzi sempre la variante Async.

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 dal server: definizione Proto

Lo streaming dal server aggiunge la parola chiave stream prima del tipo di risposta. Il server invia più messaggi sulla stessa connessione prima di chiudere il flusso.

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; }

Implementare lo streaming dal server

Utilizzi IServerStreamWriter<T> per inviare i messaggi. Il metodo restituisce una Task: scriva finché non ha terminato, quindi restituisca il controllo.

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

Consumare un flusso dal server nel client

Utilizzi await foreach su ResponseStream.ReadAllAsync() per elaborare ogni messaggio non appena arriva.

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

Annullare un flusso dal server

Passi un CancellationToken quando apre la chiamata per interrompere il flusso dal lato client. Il server riceve l'annullamento tramite il proprio 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.");
}

Metadati: intestazioni della richiesta e trailer

gRPC supporta i metadati (coppie chiave-valore) inviati come intestazioni prima della risposta e come trailer dopo la risposta. Li utilizzi per i token di autenticazione, gli ID di tracing o i cursori di paginazione.

// 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 per i client browser

I browser non possono utilizzare gRPC puro (i trailer HTTP/2 non sono supportati). Utilizzi Grpc.AspNetCore.Web e il client JavaScript grpc-web, oppure Grpc.Net.Client.Web di 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 reale: servizio di streaming dei log

Un servizio di aggregazione dei log trasmette in tempo reale le voci dei log delle applicazioni ai client di monitoraggio connessi, utilizzando lo streaming dal server.

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

Verifica rapida

Quale parola chiave in un file .proto indica una RPC con streaming dal server?

Riepilogo: RPC unarie e streaming dal server

Punti chiave:

  • RPC unaria: una richiesta e una risposta — il modello più comune
  • Streaming dal server: una richiesta e più messaggi di risposta nel tempo
  • Implementi lo streaming dal server scrivendo in IServerStreamWriter<T>
  • Consumi i flussi dal server con await foreach su ReadAllAsync()
  • Utilizzi CancellationToken per interrompere correttamente i flussi da entrambi i lati
  • gRPC-Web consente ai client browser di chiamare i servizi gRPC

Domande Frequenti

La lezione «RPC unarie e streaming dal server» è gratuita?

Sì — il testo completo di «RPC unarie e streaming dal server» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso C# Academy, passa a CoddyKit PRO. Il corso C# Academy include 4 lezioni in totale.

Cosa imparerò in «RPC unarie e streaming dal server»?

Implementi chiamate unarie e streaming dal server per inviare dati in tempo reale dal server al client. Eserciti C# Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare C# Academy?

Non è richiesta alcuna esperienza precedente. C# Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 4.

Quanto tempo richiede la lezione «RPC unarie e streaming dal server»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione C# Academy?

Sì. Ogni lezione C# Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Fondamenti di gRPC e Protobuf
  2. RPC unarie e streaming dal server
  3. Streaming dal client e bidirezionale
  4. Scadenze, annullamento e interceptor
← Torna a C# Academy