Integración de la fábrica de cliente de gRPC en .NET
Nota:
Esta no es la versión más reciente de este artículo. Para la versión actual, consulte la versión .NET 8 de este artículo.
Advertencia
Esta versión de ASP.NET Core ya no se admite. Para obtener más información, consulte la Directiva de soporte técnico de .NET y .NET Core. Para la versión actual, consulte la versión .NET 8 de este artículo.
Importante
Esta información hace referencia a un producto en versión preliminar, el cual puede sufrir importantes modificaciones antes de que se publique la versión comercial. Microsoft no proporciona ninguna garantía, expresa o implícita, con respecto a la información proporcionada aquí.
Para la versión actual, consulte la versión .NET 8 de este artículo.
La integración de gRPC con HttpClientFactory
ofrece una manera centralizada de crear clientes gRPC. Se puede usar como alternativa a la configuración de instancias de cliente de gRPC independientes. La integración de fábrica está disponible en el paquete NuGet Grpc.Net.ClientFactory.
La fábrica ofrece las ventajas siguientes:
- Proporciona una ubicación central para configurar instancias de cliente de gRPC.
- Administra la duración del objeto
HttpClientMessageHandler
subyacente. - Propagación automática de la fecha límite y la cancelación en un servicio gRPC de ASP.NET Core
Registro de clientes gRPC
Para registrar un cliente gRPC, se puede usar el método de extensión genérico AddGrpcClient
dentro de una instancia de WebApplicationBuilder en el punto de entrada de la aplicación de Program.cs
, especificando la clase del cliente con tipo de gRPC y la dirección del servicio:
builder.Services.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
});
El tipo de cliente gRPC se registra como transitorio con la inserción de dependencias (DI). Ahora el cliente se puede insertar y consumir directamente en los tipos creados por inserción de dependencias. Los controladores de ASP.NET Core MVC, los concentradores de SignalR y los servicios gRPC son lugares en los que se pueden insertar clientes gRPC de forma automática:
public class AggregatorService : Aggregator.AggregatorBase
{
private readonly Greeter.GreeterClient _client;
public AggregatorService(Greeter.GreeterClient client)
{
_client = client;
}
public override async Task SayHellos(HelloRequest request,
IServerStreamWriter<HelloReply> responseStream, ServerCallContext context)
{
// Forward the call on to the greeter service
using (var call = _client.SayHellos(request))
{
await foreach (var response in call.ResponseStream.ReadAllAsync())
{
await responseStream.WriteAsync(response);
}
}
}
}
Configuración de HttpHandler
HttpClientFactory
crea el objeto HttpMessageHandler
que usa el cliente gRPC. Se pueden usar métodos HttpClientFactory
estándar para agregar middleware de solicitud de salida o para configurar el objeto HttpClientHandler
subyacente de HttpClient
:
builder.Services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.ConfigurePrimaryHttpMessageHandler(() =>
{
var handler = new HttpClientHandler();
handler.ClientCertificates.Add(LoadCertificate());
return handler;
});
Para obtener más información, vea Realización de solicitudes HTTP con IHttpClientFactory.
Configuración de interceptores
Los interceptores gRPC se pueden agregar a los clientes usando el método AddInterceptor
.
builder.Services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.AddInterceptor<LoggingInterceptor>();
El código anterior:
- Registra el tipo
GreeterClient
. - Configura un
LoggingInterceptor
para este cliente.LoggingInterceptor
se crea una vez y se comparte entre las instancias deGreeterClient
.
De forma predeterminada, se crea un interceptor una vez y se comparte entre los clientes. Este comportamiento se puede invalidar especificando un ámbito cuando se registra un interceptor. El generador de clientes se puede configurar para crear un nuevo interceptor para cada cliente especificando InterceptorScope.Client
.
builder.Services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.AddInterceptor<LoggingInterceptor>(InterceptorScope.Client);
La creación de interceptores con ámbito de cliente es útil cuando un interceptor requiere servicios con ámbito o transitorios desde la inserción de dependencias.
Un interceptor de gRPC o credenciales de canal pueden usarse para enviar metadatos Authorization
con cada solicitud. Para obtener más información sobre cómo configurar la autenticación, consulte la sección sobre cómo enviar un token de portador con la fábrica de cliente de gRPC.
Configuración del canal
Se puede aplicar una configuración adicional a un canal con el método ConfigureChannel
:
builder.Services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.ConfigureChannel(o =>
{
o.Credentials = new CustomCredentials();
});
A ConfigureChannel
se le pasa una instancia de GrpcChannelOptions
. Para obtener más información, vea Configuración de opciones de cliente.
Nota:
Algunas propiedades se establecen en GrpcChannelOptions
antes de ejecutar la devolución de llamada ConfigureChannel
:
HttpHandler
se establece en el resultado de ConfigurePrimaryHttpMessageHandler.LoggerFactory
se establece en el ILoggerFactory resuelto con la inserción de dependencias.
Estos valores se pueden invalidar con ConfigureChannel
.
Credenciales de llamada
Se puede agregar un encabezado de autenticación a las llamadas de gRPC mediante el método AddCallCredentials
:
builder.Services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.AddCallCredentials((context, metadata) =>
{
if (!string.IsNullOrEmpty(_token))
{
metadata.Add("Authorization", $"Bearer {_token}");
}
return Task.CompletedTask;
});
Para obtener más información sobre cómo configurar las credenciales de llamada, consulte la sección sobre cómo enviar un token de portador con la fábrica de cliente de gRPC.
Propagación de la fecha límite y la cancelación
Los clientes gRPC creados por la fábrica en un servicio gRPC se pueden configurar con EnableCallContextPropagation()
para propagar automáticamente la fecha límite y el token de cancelación a las llamadas secundarias. El método de extensión EnableCallContextPropagation()
está disponible en el paquete NuGet Grpc.AspNetCore.Server.ClientFactory.
La propagación del contexto de llamada funciona mediante la lectura de la fecha límite y el token de cancelación del contexto de solicitud gRPC actual y su propagación automática a las llamadas salientes realizadas por el cliente gRPC. La propagación del contexto de llamada es una excelente manera de garantizar que los escenarios complejos de gRPC anidados siempre propagan la fecha límite y la cancelación.
builder.Services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.EnableCallContextPropagation();
De forma predeterminada, EnableCallContextPropagation
genera un error si el cliente se usa fuera del contexto de una llamada a gRPC. El error se ha diseñado para avisarle de que no hay un contexto de llamada que propagar. Si desea utilizar el cliente fuera de un contexto de llamada, suprima el error cuando el cliente esté configurado con SuppressContextNotFoundErrors
:
builder.Services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.EnableCallContextPropagation(o => o.SuppressContextNotFoundErrors = true);
Para más información sobre las fechas límite y la cancelación de RPC, vea Servicios gRPC confiables con fechas límite y cancelación.
Clientes con nombre
Normalmente, un tipo de cliente gRPC se registra una vez y, a continuación, se inserta directamente en el constructor de un tipo mediante DI. Sin embargo, hay escenarios en los que resulta útil tener varias configuraciones para un cliente. Por ejemplo, un cliente que realiza llamadas gRPC con y sin autenticación.
Para registrar varios clientes con el mismo tipo, asigne un nombre a cada cliente. Cada cliente con nombre puede tener su propia configuración. El método de extensión AddGrpcClient
genérico tiene una sobrecarga que incluye un parámetro de nombre:
builder.Services
.AddGrpcClient<Greeter.GreeterClient>("Greeter", o =>
{
o.Address = new Uri("https://localhost:5001");
});
builder.Services
.AddGrpcClient<Greeter.GreeterClient>("GreeterAuthenticated", o =>
{
o.Address = new Uri("https://localhost:5001");
})
.ConfigureChannel(o =>
{
o.Credentials = new CustomCredentials();
});
El código anterior:
- Registra el tipo
GreeterClient
dos veces, especificando un nombre único cada vez. - Configura diferentes opciones para cada cliente con nombre. El registro
GreeterAuthenticated
agrega credenciales al canal para que se autentiquen las llamadas gRPC realizadas con él.
Se crea un cliente gRPC con nombre en el código de la aplicación mediante GrpcClientFactory
. El tipo y el nombre del cliente deseado se especifican mediante el método GrpcClientFactory.CreateClient
genérico:
public class AggregatorService : Aggregator.AggregatorBase
{
private readonly Greeter.GreeterClient _client;
public AggregatorService(GrpcClientFactory grpcClientFactory)
{
_client = grpcClientFactory.CreateClient<Greeter.GreeterClient>("GreeterAuthenticated");
}
}
Recursos adicionales
La integración de gRPC con HttpClientFactory
ofrece una manera centralizada de crear clientes gRPC. Se puede usar como alternativa a la configuración de instancias de cliente de gRPC independientes. La integración de fábrica está disponible en el paquete NuGet Grpc.Net.ClientFactory.
La fábrica ofrece las ventajas siguientes:
- Proporciona una ubicación central para configurar instancias de cliente de gRPC.
- Administra la duración del objeto
HttpClientMessageHandler
subyacente. - Propagación automática de la fecha límite y la cancelación en un servicio gRPC de ASP.NET Core
Registro de clientes gRPC
Para registrar un cliente gRPC, se puede usar el método de extensión genérico AddGrpcClient
dentro de Startup.ConfigureServices
, y especificar la clase del cliente con tipo de gRPC y la dirección del servicio:
services.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
});
El tipo de cliente gRPC se registra como transitorio con la inserción de dependencias (DI). Ahora el cliente se puede insertar y consumir directamente en los tipos creados por inserción de dependencias. Los controladores de ASP.NET Core MVC, los concentradores de SignalR y los servicios gRPC son lugares en los que se pueden insertar clientes gRPC de forma automática:
public class AggregatorService : Aggregator.AggregatorBase
{
private readonly Greeter.GreeterClient _client;
public AggregatorService(Greeter.GreeterClient client)
{
_client = client;
}
public override async Task SayHellos(HelloRequest request,
IServerStreamWriter<HelloReply> responseStream, ServerCallContext context)
{
// Forward the call on to the greeter service
using (var call = _client.SayHellos(request))
{
await foreach (var response in call.ResponseStream.ReadAllAsync())
{
await responseStream.WriteAsync(response);
}
}
}
}
Configuración de HttpHandler
HttpClientFactory
crea el objeto HttpMessageHandler
que usa el cliente gRPC. Se pueden usar métodos HttpClientFactory
estándar para agregar middleware de solicitud de salida o para configurar el objeto HttpClientHandler
subyacente de HttpClient
:
services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.ConfigurePrimaryHttpMessageHandler(() =>
{
var handler = new HttpClientHandler();
handler.ClientCertificates.Add(LoadCertificate());
return handler;
});
Para obtener más información, vea Realización de solicitudes HTTP con IHttpClientFactory.
Configuración de interceptores
Los interceptores gRPC se pueden agregar a los clientes usando el método AddInterceptor
.
services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.AddInterceptor<LoggingInterceptor>();
El código anterior:
- Registra el tipo
GreeterClient
. - Configura un
LoggingInterceptor
para este cliente.LoggingInterceptor
se crea una vez y se comparte entre las instancias deGreeterClient
.
De forma predeterminada, se crea un interceptor una vez y se comparte entre los clientes. Este comportamiento se puede invalidar especificando un ámbito cuando se registra un interceptor. El generador de clientes se puede configurar para crear un nuevo interceptor para cada cliente especificando InterceptorScope.Client
.
services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.AddInterceptor<LoggingInterceptor>(InterceptorScope.Client);
La creación de interceptores con ámbito de cliente es útil cuando un interceptor requiere servicios con ámbito o transitorios desde la inserción de dependencias.
Un interceptor de gRPC o credenciales de canal pueden usarse para enviar metadatos Authorization
con cada solicitud. Para obtener más información sobre cómo configurar la autenticación, consulte la sección sobre cómo enviar un token de portador con la fábrica de cliente de gRPC.
Configuración del canal
Se puede aplicar una configuración adicional a un canal con el método ConfigureChannel
:
services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.ConfigureChannel(o =>
{
o.Credentials = new CustomCredentials();
});
A ConfigureChannel
se le pasa una instancia de GrpcChannelOptions
. Para obtener más información, vea Configuración de opciones de cliente.
Nota:
Algunas propiedades se establecen en GrpcChannelOptions
antes de ejecutar la devolución de llamada ConfigureChannel
:
HttpHandler
se establece en el resultado de ConfigurePrimaryHttpMessageHandler.LoggerFactory
se establece en el ILoggerFactory resuelto con la inserción de dependencias.
Estos valores se pueden invalidar con ConfigureChannel
.
Propagación de la fecha límite y la cancelación
Los clientes gRPC creados por la fábrica en un servicio gRPC se pueden configurar con EnableCallContextPropagation()
para propagar automáticamente la fecha límite y el token de cancelación a las llamadas secundarias. El método de extensión EnableCallContextPropagation()
está disponible en el paquete NuGet Grpc.AspNetCore.Server.ClientFactory.
La propagación del contexto de llamada funciona mediante la lectura de la fecha límite y el token de cancelación del contexto de solicitud gRPC actual y su propagación automática a las llamadas salientes realizadas por el cliente gRPC. La propagación del contexto de llamada es una excelente manera de garantizar que los escenarios complejos de gRPC anidados siempre propagan la fecha límite y la cancelación.
services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.EnableCallContextPropagation();
De forma predeterminada, EnableCallContextPropagation
genera un error si el cliente se usa fuera del contexto de una llamada a gRPC. El error se ha diseñado para avisarle de que no hay un contexto de llamada que propagar. Si desea utilizar el cliente fuera de un contexto de llamada, suprima el error cuando el cliente esté configurado con SuppressContextNotFoundErrors
:
services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.EnableCallContextPropagation(o => o.SuppressContextNotFoundErrors = true);
Para más información sobre las fechas límite y la cancelación de RPC, vea Servicios gRPC confiables con fechas límite y cancelación.
Clientes con nombre
Normalmente, un tipo de cliente gRPC se registra una vez y, a continuación, se inserta directamente en el constructor de un tipo mediante DI. Sin embargo, hay escenarios en los que resulta útil tener varias configuraciones para un cliente. Por ejemplo, un cliente que realiza llamadas gRPC con y sin autenticación.
Para registrar varios clientes con el mismo tipo, asigne un nombre a cada cliente. Cada cliente con nombre puede tener su propia configuración. El método de extensión AddGrpcClient
genérico tiene una sobrecarga que incluye un parámetro de nombre:
services
.AddGrpcClient<Greeter.GreeterClient>("Greeter", o =>
{
o.Address = new Uri("https://localhost:5001");
});
services
.AddGrpcClient<Greeter.GreeterClient>("GreeterAuthenticated", o =>
{
o.Address = new Uri("https://localhost:5001");
})
.ConfigureChannel(o =>
{
o.Credentials = new CustomCredentials();
});
El código anterior:
- Registra el tipo
GreeterClient
dos veces, especificando un nombre único cada vez. - Configura diferentes opciones para cada cliente con nombre. El registro
GreeterAuthenticated
agrega credenciales al canal para que se autentiquen las llamadas gRPC realizadas con él.
Se crea un cliente gRPC con nombre en el código de la aplicación mediante GrpcClientFactory
. El tipo y el nombre del cliente deseado se especifican mediante el método GrpcClientFactory.CreateClient
genérico:
public class AggregatorService : Aggregator.AggregatorBase
{
private readonly Greeter.GreeterClient _client;
public AggregatorService(GrpcClientFactory grpcClientFactory)
{
_client = grpcClientFactory.CreateClient<Greeter.GreeterClient>("GreeterAuthenticated");
}
}