RPCs unários e transmissão pelo servidor
Implemente chamadas unárias e transmissão pelo servidor para enviar dados do servidor ao cliente em tempo real.
RPCs unários e transmissão pelo servidor é uma aula grátis de C# Academy no CoddyKit. Esta é a aula 2 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de C# Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de C# Academy inclui 4 aulas no total.
Tipos de RPC do gRPC
O gRPC oferece suporte a quatro padrões de RPC: Unária (solicitação/resposta), Transmissão do Servidor (o cliente envia uma, o servidor envia várias), Transmissão do Cliente e Transmissão Bidirecional. Esta lição aborda os dois primeiros.
RPC Unária: O Padrão Básico
A RPC unária é o padrão mais simples: uma solicitação e uma resposta. Ela se parece com uma chamada de função normal, mas é transportada por HTTP/2 com codificação 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; }Implementando uma RPC Unária
Substitua o método base gerado. O ServerCallContext fornece metadados, token de cancelamento, prazo limite e informações do 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
};
}
}Chamando uma RPC unária de um cliente
O cliente gerado fornece métodos com aparência síncrona e métodos verdadeiramente assíncronos. Sempre use a variante Async em produção.
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}");Transmissão pelo servidor: definição do proto
A transmissão pelo servidor adiciona a palavra-chave stream antes do tipo de resposta. O servidor envia várias mensagens pela mesma conexão antes de fechar a transmissão.
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; }Implementando a transmissão pelo servidor
Use IServerStreamWriter<T> para enviar mensagens. O método retorna uma Task — escreva até terminar e, então, retorne.
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);
}
}Consumindo uma transmissão do servidor no cliente
Use await foreach em ResponseStream.ReadAllAsync() para processar cada mensagem à medida que ela chega.
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 cancelsCancelando uma transmissão do servidor
Passe um CancellationToken ao abrir a chamada para interromper a transmissão no lado do cliente. O servidor recebe o cancelamento por meio do próprio 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.");
}Metadados: cabeçalhos de solicitação e cabeçalhos finais
O gRPC oferece suporte a metadados (pares de chave e valor) enviados como cabeçalhos antes da resposta e como cabeçalhos finais depois dela. Use-os para tokens de autenticação, identificadores de rastreamento ou cursores de paginação.
// 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
Os navegadores não podem usar gRPC direto (os cabeçalhos finais do HTTP/2 não são compatíveis). Use Grpc.AspNetCore.Web e o cliente JavaScript grpc-web ou o Grpc.Net.Client.Web do 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 });Na prática: serviço de transmissão de registros
Um serviço de agregação de registros transmite entradas de registro da aplicação para clientes de monitoramento conectados em tempo real usando a transmissão pelo 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)
});
}
}
}Verificação rápida
Qual palavra-chave em um arquivo .proto indica uma RPC de transmissão pelo servidor?
Recapitulação: RPCs unárias e de transmissão pelo servidor
Principais conclusões:
- RPC unária: uma solicitação e uma resposta — o padrão mais comum
- Transmissão pelo servidor: uma solicitação e várias mensagens de resposta ao longo do tempo
- Implemente a transmissão pelo servidor escrevendo em
IServerStreamWriter<T> - Consuma transmissões do servidor com
await foreachemReadAllAsync() - Use CancellationToken para interromper transmissões de forma controlada em qualquer um dos lados
- O gRPC-Web permite que clientes de navegador chamem serviços gRPC
Perguntas Frequentes
A aula “RPCs unários e transmissão pelo servidor” é grátis?
Sim — o texto completo de “RPCs unários e transmissão pelo servidor” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de C# Academy, atualize para CoddyKit PRO. O curso de C# Academy inclui 4 aulas no total.
O que vou aprender em “RPCs unários e transmissão pelo servidor”?
Implemente chamadas unárias e transmissão pelo servidor para enviar dados do servidor ao cliente em tempo real. Você pratica C# Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar C# Academy?
Nenhuma experiência prévia é necessária. C# Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 4.
Quanto tempo leva a aula “RPCs unários e transmissão pelo servidor”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de C# Academy?
Sim. Cada aula de C# Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Fundamentos de gRPC e Protobuf
- RPCs unários e transmissão pelo servidor
- Transmissão pelo cliente e bidirecional
- Prazos, cancelamento e interceptadores