Eventos
Junte-se a nós na FabCon Vegas
31 de mar., 23 - 2 de abr., 23
O melhor evento liderado pela comunidade Microsoft Fabric, Power BI, SQL e AI. 31 de março a 2 de abril de 2025.
Registre-se hoje mesmoNão há mais suporte para esse navegador.
Atualize o Microsoft Edge para aproveitar os recursos, o suporte técnico e as atualizações de segurança mais recentes.
Observação
Esta não é a versão mais recente deste artigo. Para a versão atual, consulte a versão .NET 9 deste artigo.
Aviso
Esta versão do ASP.NET Core não tem mais suporte. Para obter mais informações, consulte a Política de Suporte do .NET e do .NET Core. Para a versão atual, consulte a versão .NET 9 deste artigo.
Importante
Essas informações relacionam-se ao produto de pré-lançamento, que poderá ser substancialmente modificado antes do lançamento comercial. A Microsoft não oferece nenhuma garantia, explícita ou implícita, quanto às informações fornecidas aqui.
Para a versão atual, consulte a versão .NET 9 deste artigo.
Uma biblioteca de clientes gRPC do .NET está disponível no pacote NuGet Grpc.Net.Client. Este documento explica como:
Os clientes gRPC são tipos de cliente concretos gerados a partir de arquivos .proto
. O cliente gRPC concreto tem métodos que se traduzem para o serviço gRPC no arquivo .proto
. Por exemplo, um serviço chamado Greeter
gera um tipo GreeterClient
com métodos para chamar o serviço.
Um cliente gRPC é criado a partir de um canal. Comece usando GrpcChannel.ForAddress
para criar um canal e, em seguida, use o canal para criar um cliente gRPC:
var channel = GrpcChannel.ForAddress("https://localhost:5001");
var client = new Greet.GreeterClient(channel);
Um canal representa uma conexão de longa duração com um serviço gRPC. Quando um canal é criado, ele é configurado com opções relacionadas à chamada de um serviço. Por exemplo, o HttpClient
usado para fazer chamadas, o tamanho máximo da mensagem de envio e recebimento e o registro em log podem ser especificados em GrpcChannelOptions
e usados com GrpcChannel.ForAddress
. Para obter uma lista completa de opções, consulte opções de configuração do cliente.
var channel = GrpcChannel.ForAddress("https://localhost:5001");
var greeterClient = new Greet.GreeterClient(channel);
var counterClient = new Count.CounterClient(channel);
// Use clients to call gRPC services
Um cliente gRPC deve usar a mesma segurança em nível de conexão que o serviço chamado. O TLS do cliente gRPC é configurado quando o canal gRPC é criado. Um cliente gRPC lança um erro quando chama um serviço e a segurança em nível de conexão do canal e do serviço não correspondem.
Para configurar um canal gRPC para usar o TLS, verifique se o endereço do servidor começa com https
. Por exemplo, GrpcChannel.ForAddress("https://localhost:5001")
usa o protocolo HTTPS. O canal gRPC negocia automaticamente uma conexão protegida pelo TLS e usa uma conexão segura para fazer chamadas gRPC.
Dica
O gRPC dá suporte à autenticação de certificado do cliente por TLS. Para obter informações sobre como configurar certificados de cliente com um canal gRPC, consulte Autenticação e autorização no gRPC para ASP.NET Core.
Para chamar serviços gRPC não seguros, verifique se o endereço do servidor começa com http
. Por exemplo, GrpcChannel.ForAddress("http://localhost:5000")
usa o protocolo HTTPS. No .NET Core 3.1, é necessária uma configuração adicional para chamar serviços gRPC não seguros com o cliente .NET.
Desempenho e uso do canal e do cliente:
GrpcChannel.ForAddress
não é a única opção para criar um cliente gRPC. Se chamar serviços gRPC de um aplicativo ASP.NET Core, considere a integração de fábrica do cliente gRPC. A integração do gRPC com HttpClientFactory
oferece uma alternativa centralizada para a criação de clientes gRPC.
Observação
No momento, não há suporte para chamar gRPC por HTTP/2 com Grpc.Net.Client
no Xamarin. Estamos trabalhando para melhorar o suporte a HTTP/2 em uma versão futura do Xamarin. Grpc.Core e gRPC-Web são alternativas viáveis que funcionam hoje.
Uma chamada gRPC é iniciada chamando um método no cliente. O cliente gRPC manipulará a serialização de mensagens e abordará a chamada gRPC para o serviço correto.
O gRPC tem diferentes tipos de métodos. Como o cliente é usado para fazer uma chamada gRPC depende do tipo de método chamado. Os tipos de método gRPC são:
Uma chamada unária começa com o cliente enviando uma mensagem de solicitação. Uma mensagem de resposta é retornada quando o serviço é concluído.
var client = new Greet.GreeterClient(channel);
var response = await client.SayHelloAsync(new HelloRequest { Name = "World" });
Console.WriteLine("Greeting: " + response.Message);
// Greeting: Hello World
Cada método de serviço unário no arquivo .proto
resultará em dois métodos .NET no tipo de cliente gRPC concreto para chamar o método: um método assíncrono e um método de bloqueio. Por exemplo, em GreeterClient
, há duas maneiras de chamar SayHello
:
GreeterClient.SayHelloAsync
– chama o serviço Greeter.SayHello
de forma assíncrona. Pode ser aguardado.GreeterClient.SayHello
– chama o serviço Greeter.SayHello
e bloqueia até a conclusão. Não use em código assíncrono.Uma chamada de streaming de servidor começa com o cliente enviando uma mensagem de solicitação. ResponseStream.MoveNext()
lê mensagens transmitidas do serviço. A chamada de streaming de servidor é concluída quando ResponseStream.MoveNext()
retorna false
.
var client = new Greet.GreeterClient(channel);
using var call = client.SayHellos(new HelloRequest { Name = "World" });
while (await call.ResponseStream.MoveNext())
{
Console.WriteLine("Greeting: " + call.ResponseStream.Current.Message);
// "Greeting: Hello World" is written multiple times
}
Ao usar o C# 8 ou posterior, a sintaxe await foreach
pode ser usada para ler mensagens. O método de extensão IAsyncStreamReader<T>.ReadAllAsync()
lê todas as mensagens do fluxo de resposta:
var client = new Greet.GreeterClient(channel);
using var call = client.SayHellos(new HelloRequest { Name = "World" });
await foreach (var response in call.ResponseStream.ReadAllAsync())
{
Console.WriteLine("Greeting: " + response.Message);
// "Greeting: Hello World" is written multiple times
}
O tipo retornado do início de uma chamada de streaming do servidor implementa IDisposable
. Sempre descarte uma chamada de streaming para garantir que ela seja interrompida e que todos os recursos sejam limpos.
Uma chamada de streaming de cliente é iniciada sem que o cliente envie uma mensagem. O cliente pode optar por enviar mensagens com RequestStream.WriteAsync
. Quando o cliente termina de enviar mensagens, RequestStream.CompleteAsync()
deverá ser chamado para notificar o serviço. A chamada é concluída quando o serviço retorna uma mensagem de resposta.
var client = new Counter.CounterClient(channel);
using var call = client.AccumulateCount();
for (var i = 0; i < 3; i++)
{
await call.RequestStream.WriteAsync(new CounterRequest { Count = 1 });
}
await call.RequestStream.CompleteAsync();
var response = await call;
Console.WriteLine($"Count: {response.Count}");
// Count: 3
O tipo retornado do início de uma chamada de streaming do cliente implementa IDisposable
. Sempre descarte uma chamada de streaming para garantir que ela seja interrompida e que todos os recursos sejam limpos.
Uma chamada de streaming bidirecional é iniciada sem que o cliente envie uma mensagem. O cliente pode optar por enviar mensagens com RequestStream.WriteAsync
. As mensagens transmitidas do serviço são acessíveis com ResponseStream.MoveNext()
ou ResponseStream.ReadAllAsync()
. A chamada de streaming bidirecional é concluída quando o ResponseStream
não tem mais mensagens.
var client = new Echo.EchoClient(channel);
using var call = client.Echo();
Console.WriteLine("Starting background task to receive messages");
var readTask = Task.Run(async () =>
{
await foreach (var response in call.ResponseStream.ReadAllAsync())
{
Console.WriteLine(response.Message);
// Echo messages sent to the service
}
});
Console.WriteLine("Starting to send messages");
Console.WriteLine("Type a message to echo then press enter.");
while (true)
{
var result = Console.ReadLine();
if (string.IsNullOrEmpty(result))
{
break;
}
await call.RequestStream.WriteAsync(new EchoMessage { Message = result });
}
Console.WriteLine("Disconnecting");
await call.RequestStream.CompleteAsync();
await readTask;
Para obter o melhor desempenho e evitar erros desnecessários no cliente e no serviço, tente concluir chamadas de streaming bidirecionais normalmente. Uma chamada bidirecional é concluída normalmente quando o servidor termina de ler o fluxo de solicitação e o cliente termina de ler o fluxo de resposta. A chamada de exemplo anterior é um exemplo de uma chamada bidirecional que termina normalmente. Na chamada, o cliente:
EchoClient.Echo
.ResponseStream.ReadAllAsync()
.RequestStream.WriteAsync
.RequestStream.CompleteAsync()
.Durante uma chamada de streaming bidirecional, o cliente e o serviço podem enviar mensagens entre si a qualquer momento. A melhor lógica de cliente para interagir com uma chamada bidirecional varia dependendo da lógica de serviço.
O tipo retornado do início de uma chamada de streaming bidirecional implementa IDisposable
. Sempre descarte uma chamada de streaming para garantir que ela seja interrompida e que todos os recursos sejam limpos.
As chamadas gRPC retornam cabeçalhos de resposta. Os cabeçalhos de resposta HTTP passam metadados de nome/valor sobre uma chamada que não está relacionada à mensagem retornada.
Os cabeçalhos são acessíveis usando ResponseHeadersAsync
, que retorna uma coleção de metadados. Os cabeçalhos normalmente são retornados com a mensagem de resposta; portanto, você deve aguardá-los.
var client = new Greet.GreeterClient(channel);
using var call = client.SayHelloAsync(new HelloRequest { Name = "World" });
var headers = await call.ResponseHeadersAsync;
var myValue = headers.GetValue("my-trailer-name");
var response = await call.ResponseAsync;
Uso de ResponseHeadersAsync
:
ResponseHeadersAsync
para obter a coleção de cabeçalhos.ResponseAsync
(ou o fluxo de resposta ao transmitir por streaming). Se uma resposta tiver sido retornada, ResponseHeadersAsync
retornará cabeçalhos instantaneamente.As chamadas gRPC podem retornar trailers de resposta. Os trailers são usados para fornecer metadados de nome/valor sobre uma chamada. Os trailers fornecem funcionalidade semelhante aos cabeçalhos HTTP, mas são recebidos no final da chamada.
Os cabeçalhos são acessíveis usando GetTrailers()
, que retorna uma coleção de metadados. Os trailers são retornados após a conclusão da resposta. Portanto, você deve aguardar todas as mensagens de resposta antes de acessar os trailers.
As chamadas de streaming unárias e de cliente devem aguardar ResponseAsync
antes de chamar GetTrailers()
:
var client = new Greet.GreeterClient(channel);
using var call = client.SayHelloAsync(new HelloRequest { Name = "World" });
var response = await call.ResponseAsync;
Console.WriteLine("Greeting: " + response.Message);
// Greeting: Hello World
var trailers = call.GetTrailers();
var myValue = trailers.GetValue("my-trailer-name");
As chamadas de streaming de servidor e bidirecional devem terminar de aguardar o fluxo de resposta antes de chamar GetTrailers()
:
var client = new Greet.GreeterClient(channel);
using var call = client.SayHellos(new HelloRequest { Name = "World" });
await foreach (var response in call.ResponseStream.ReadAllAsync())
{
Console.WriteLine("Greeting: " + response.Message);
// "Greeting: Hello World" is written multiple times
}
var trailers = call.GetTrailers();
var myValue = trailers.GetValue("my-trailer-name");
Os trailers também podem ser acessados por meio de RpcException
. Um serviço pode retornar trailers junto com uma status gRPC diferente de OK. Nessa situação, os trailers são recuperados da exceção gerada pelo cliente gRPC:
var client = new Greet.GreeterClient(channel);
string myValue = null;
try
{
using var call = client.SayHelloAsync(new HelloRequest { Name = "World" });
var response = await call.ResponseAsync;
Console.WriteLine("Greeting: " + response.Message);
// Greeting: Hello World
var trailers = call.GetTrailers();
myValue = trailers.GetValue("my-trailer-name");
}
catch (RpcException ex)
{
var trailers = ex.Trailers;
myValue = trailers.GetValue("my-trailer-name");
}
É recomendável configurar um prazo de chamada gRPC porque ele fornece o tempo máximo de execução de uma chamada. Ela impede que serviços funcionando de forma inadequada sejam executados para sempre e o esgotamento dos recursos do servidor. Os prazos são uma ferramenta útil para compilar aplicativos confiáveis.
Configure CallOptions.Deadline
para definir um prazo para uma chamada gRPC:
var client = new Greet.GreeterClient(channel);
try
{
var response = await client.SayHelloAsync(
new HelloRequest { Name = "World" },
deadline: DateTime.UtcNow.AddSeconds(5));
// Greeting: Hello World
Console.WriteLine("Greeting: " + response.Message);
}
catch (RpcException ex) when (ex.StatusCode == StatusCode.DeadlineExceeded)
{
Console.WriteLine("Greeting timeout.");
}
Para obter mais informações, consulte Serviços gRPC confiáveis com prazos finais e cancelamento.
Comentários do ASP.NET Core
O ASP.NET Core é um projeto código aberto. Selecione um link para fornecer comentários:
Eventos
Junte-se a nós na FabCon Vegas
31 de mar., 23 - 2 de abr., 23
O melhor evento liderado pela comunidade Microsoft Fabric, Power BI, SQL e AI. 31 de março a 2 de abril de 2025.
Registre-se hoje mesmo