Llamar a gRPC Services con el cliente de .NETCall gRPC services with the .NET client

Hay una biblioteca de cliente de .NET gRPC disponible en el paquete NuGet de gRPC .net. Client .A .NET gRPC client library is available in the Grpc.Net.Client NuGet package. En este documento se explica cómo:This document explains how to:

  • Configure un cliente de gRPC para llamar a los servicios de gRPC.Configure a gRPC client to call gRPC services.
  • Realice llamadas gRPC a los métodos unario, streaming de servidor, streaming de cliente y streaming bidireccional.Make gRPC calls to unary, server streaming, client streaming, and bi-directional streaming methods.

Configurar el cliente de gRPCConfigure gRPC client

Los clientes gRPC son tipos de cliente concretos que se generan a partir de archivos *.proto.gRPC clients are concrete client types that are generated from *.proto files. El cliente gRPC concreto tiene métodos que se convierten en el servicio gRPC en el archivo *.proto.The concrete gRPC client has methods that translate to the gRPC service in the *.proto file.

Se crea un cliente de gRPC a partir de un canal.A gRPC client is created from a channel. Empiece por usar GrpcChannel.ForAddress para crear un canal y, a continuación, use el canal para crear un cliente de gRPC:Start by using GrpcChannel.ForAddress to create a channel, and then use the channel to create a gRPC client:

var channel = GrpcChannel.ForAddress("https://localhost:5001");
var client = new Greet.GreeterClient(channel);

Un canal representa una conexión de larga duración con un servicio de gRPC.A channel represents a long-lived connection to a gRPC service. Cuando se crea un canal, se configura con opciones relacionadas con la llamada a un servicio.When a channel is created, it is configured with options related to calling a service. Por ejemplo, la HttpClient utilizada para realizar llamadas, el tamaño máximo del mensaje de envío y recepción y el registro se pueden especificar en GrpcChannelOptions y usar con GrpcChannel.ForAddress.For example, the HttpClient used to make calls, the maximum send and receive message size, and logging can be specified on GrpcChannelOptions and used with GrpcChannel.ForAddress. Para obtener una lista completa de opciones, vea Opciones de configuración de cliente.For a complete list of options, see client configuration options.

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

Rendimiento y uso de canal y cliente:Channel and client performance and usage:

  • La creación de un canal puede ser una operación costosa.Creating a channel can be an expensive operation. La reutilización de un canal para las llamadas de gRPC proporciona ventajas de rendimiento.Reusing a channel for gRPC calls provides performance benefits.
  • los clientes de gRPC se crean con canales.gRPC clients are created with channels. los clientes de gRPC son objetos ligeros y no es necesario que estén almacenados en caché o reutilizados.gRPC clients are lightweight objects and don't need to be cached or reused.
  • Se pueden crear varios clientes de gRPC a partir de un canal, incluidos distintos tipos de clientes.Multiple gRPC clients can be created from a channel, including different types of clients.
  • Varios subprocesos pueden usar de forma segura un canal y los clientes creados a partir del canal.A channel and clients created from the channel can safely be used by multiple threads.
  • Los clientes creados desde el canal pueden realizar varias llamadas simultáneas.Clients created from the channel can make multiple simultaneous calls.

GrpcChannel.ForAddress no es la única opción para crear un cliente de gRPC.GrpcChannel.ForAddress isn't the only option for creating a gRPC client. Si está llamando a gRPC Services desde una aplicación ASP.NET Core, considere la integración de fábrica de cliente de gRPC.If you're calling gRPC services from an ASP.NET Core app, consider gRPC client factory integration. la integración de gRPC con HttpClientFactory ofrece una alternativa centralizada para la creación de clientes de gRPC.gRPC integration with HttpClientFactory offers a centralized alternative to creating gRPC clients.

Nota

Se requiere configuración adicional para llamar a los servicios de gRPC inseguros con el cliente de .net.Additional configuration is required to call insecure gRPC services with the .NET client.

Realizar llamadas gRPCMake gRPC calls

Una llamada a gRPC se inicia llamando a un método en el cliente.A gRPC call is initiated by calling a method on the client. El cliente gRPC controlará la serialización del mensaje y dirigirá la llamada gRPC al servicio correcto.The gRPC client will handle message serialization and addressing the gRPC call to the correct service.

gRPC tiene distintos tipos de métodos.gRPC has different types of methods. La forma de usar el cliente para realizar una llamada gRPC depende del tipo de método al que se está llamando.How you use the client to make a gRPC call depends on the type of method you are calling. Los tipos de método gRPC son:The gRPC method types are:

  • UnarioUnary
  • Streaming de servidorServer streaming
  • Streaming de clienteClient streaming
  • Streaming bidireccionalBi-directional streaming

Llamada unariaUnary call

Una llamada unaria comienza con el cliente que envía un mensaje de solicitud.A unary call starts with the client sending a request message. Cuando finaliza el servicio, se devuelve un mensaje de respuesta.A response message is returned when the service finishes.

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 servicio unario del archivo *. proto dará como resultado dos métodos .net en el tipo de cliente gRPC concreto para llamar al método: un método asincrónico y un método de bloqueo.Each unary service method in the *.proto file will result in two .NET methods on the concrete gRPC client type for calling the method: an asynchronous method and a blocking method. Por ejemplo, en GreeterClient hay dos maneras de llamar a SayHello:For example, on GreeterClient there are two ways of calling SayHello:

  • GreeterClient.SayHelloAsync: llama a Greeter.SayHello servicio de forma asincrónica.GreeterClient.SayHelloAsync - calls Greeter.SayHello service asynchronously. Se puede esperar.Can be awaited.
  • GreeterClient.SayHello: llama a Greeter.SayHello servicio y se bloquea hasta que se completa.GreeterClient.SayHello - calls Greeter.SayHello service and blocks until complete. No se usa en código asincrónico.Don't use in asynchronous code.

Llamada de streaming de servidorServer streaming call

Una llamada de streaming de servidor se inicia con el cliente que envía un mensaje de solicitud.A server streaming call starts with the client sending a request message. ResponseStream.MoveNext() Lee los mensajes transmitidos desde el servicio.ResponseStream.MoveNext() reads messages streamed from the service. La llamada de streaming del servidor se completa cuando ResponseStream.MoveNext() devuelve false.The server streaming call is complete when ResponseStream.MoveNext() returns 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
    }
}

Si usa C# 8 o posterior, se puede usar la sintaxis de await foreach para leer los mensajes.If you are using C# 8 or later, the await foreach syntax can be used to read messages. El método de extensión IAsyncStreamReader<T>.ReadAllAsync() Lee todos los mensajes de la secuencia de respuesta:The IAsyncStreamReader<T>.ReadAllAsync() extension method reads all messages from the response stream:

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

Llamada de streaming de clienteClient streaming call

Una llamada de streaming de cliente se inicia sin que el cliente envíe un mensaje.A client streaming call starts without the client sending a message. El cliente puede elegir enviar mensajes con RequestStream.WriteAsync.The client can choose to send messages with RequestStream.WriteAsync. Cuando el cliente ha terminado de enviar mensajes RequestStream.CompleteAsync se debe llamar a para notificar al servicio.When the client has finished sending messages RequestStream.CompleteAsync should be called to notify the service. La llamada finaliza cuando el servicio devuelve un mensaje de respuesta.The call is finished when the service returns a response message.

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
}

Llamada de streaming bidireccionalBi-directional streaming call

Una llamada de streaming bidireccional se inicia sin que el cliente envíe un mensaje.A bi-directional streaming call starts without the client sending a message. El cliente puede elegir enviar mensajes con RequestStream.WriteAsync.The client can choose to send messages with RequestStream.WriteAsync. Se puede obtener acceso a los mensajes transmitidos desde el servicio con ResponseStream.MoveNext() o ResponseStream.ReadAllAsync().Messages streamed from the service are accessible with ResponseStream.MoveNext() or ResponseStream.ReadAllAsync(). La llamada de streaming bidireccional se completa cuando el ResponseStream no tiene más mensajes.The bi-directional streaming call is complete when the ResponseStream has no more messages.

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

Durante una llamada de streaming bidireccional, el cliente y el servicio pueden enviar mensajes entre sí en cualquier momento.During a bi-directional streaming call, the client and service can send messages to each other at any time. La mejor lógica de cliente para interactuar con una llamada bidireccional varía en función de la lógica del servicio.The best client logic for interacting with a bi-directional call varies depending upon the service logic.

Recursos adicionalesAdditional resources