Integrazione della client factory gRPC in .NET
L'integrazione di gRPC con HttpClientFactory
offre un modo centralizzato per creare client gRPC. Può essere usato come alternativa alla configurazione di istanze client gRPC autonome. L'integrazione della factory è disponibile nel pacchetto NuGet Grpc.Net.ClientFactory .
La factory offre i vantaggi seguenti:
- Fornisce una posizione centrale per la configurazione di istanze client gRPC logiche.
- Gestisce la durata dell'oggetto sottostante
HttpClientMessageHandler
. - Propagazione automatica della scadenza e dell'annullamento in un servizio gRPC ASP.NET Core.
Registrare client gRPC
Per registrare un client gRPC, il metodo di estensione generico AddGrpcClient
può essere usato all'interno di un'istanza di nel punto di WebApplicationBuilder ingresso dell'app in Program.cs
, specificando la classe client tipizzata gRPC e l'indirizzo del servizio:
builder.Services.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
});
Il tipo di client gRPC viene registrato come temporaneo con inserimento di dipendenze (DI). Il client può ora essere inserito e usato direttamente nei tipi creati da DI. ASP.NET Core controller MVC, SignalR hub e servizi gRPC sono posti in cui i client gRPC possono essere inseriti automaticamente:
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);
}
}
}
}
Configurare HttpHandler
HttpClientFactory
crea l'oggetto HttpMessageHandler
usato dal client gRPC. I metodi standard HttpClientFactory
possono essere usati per aggiungere middleware delle richieste in uscita o per configurare il sottostante HttpClientHandler
di 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;
});
Per altre informazioni, vedere Effettuare richieste HTTP usando IHttpClientFactory.
Configurare gli intercettori
Gli intercettori gRPC possono essere aggiunti ai client usando il AddInterceptor
metodo .
builder.Services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.AddInterceptor<LoggingInterceptor>();
Il codice precedente:
- Registra il
GreeterClient
tipo. - Configura un
LoggingInterceptor
oggetto per questo client.LoggingInterceptor
viene creato una volta e condiviso traGreeterClient
istanze.
Per impostazione predefinita, un intercettatore viene creato una volta e condiviso tra i client. Questo comportamento può essere sottoposto a override specificando un ambito durante la registrazione di un intercettatore. La factory client può essere configurata per creare un nuovo intercettatore per ogni client specificando InterceptorScope.Client
.
builder.Services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.AddInterceptor<LoggingInterceptor>(InterceptorScope.Client);
La creazione di intercettori con ambito client è utile quando un intercettatore richiede servizi con ambito o temporanei da DI.
È possibile usare un intercettatore gRPC o le credenziali del canale per inviare Authorization
metadati a ogni richiesta. Per altre informazioni sulla configurazione dell'autenticazione, vedere Inviare un token di connessione con gRPC client factory.
Configurare il canale
È possibile applicare una configurazione aggiuntiva a un canale usando il ConfigureChannel
metodo:
builder.Services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.ConfigureChannel(o =>
{
o.Credentials = new CustomCredentials();
});
ConfigureChannel
viene passata un'istanza GrpcChannelOptions
. Per altre informazioni, vedere Configurare le opzioni client.
Nota
Alcune proprietà vengono impostate su GrpcChannelOptions
prima dell'esecuzione del ConfigureChannel
callback:
HttpHandler
è impostato sul risultato da ConfigurePrimaryHttpMessageHandler.LoggerFactory
è impostato sul ILoggerFactory valore risolto da DI.
Questi valori possono essere sottoposti a override da ConfigureChannel
.
Credenziali di chiamata
È possibile aggiungere un'intestazione di autenticazione alle chiamate gRPC usando il AddCallCredentials
metodo:
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;
});
Per altre informazioni sulla configurazione delle credenziali delle chiamate, vedere Token di connessione con gRPC client factory.
Propagazione della scadenza e dell'annullamento
I client gRPC creati dalla factory in un servizio gRPC possono essere configurati con EnableCallContextPropagation()
per propagare automaticamente la scadenza e il token di annullamento alle chiamate figlio. Il EnableCallContextPropagation()
metodo di estensione è disponibile nel pacchetto NuGet Grpc.AspNetCore.Server.ClientFactory .
La propagazione del contesto di chiamata funziona leggendo la scadenza e il token di annullamento dal contesto di richiesta gRPC corrente e propagandoli automaticamente alle chiamate in uscita effettuate dal client gRPC. La propagazione del contesto delle chiamate è un ottimo modo per garantire che gli scenari gRPC complessi annidati propagano sempre la scadenza e l'annullamento.
builder.Services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.EnableCallContextPropagation();
Per impostazione predefinita, EnableCallContextPropagation
genera un errore se il client viene usato all'esterno del contesto di una chiamata gRPC. L'errore è progettato per avvisare che non esiste un contesto di chiamata da propagare. Se si vuole usare il client all'esterno di un contesto di chiamata, eliminare l'errore quando il client è configurato con SuppressContextNotFoundErrors
:
builder.Services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.EnableCallContextPropagation(o => o.SuppressContextNotFoundErrors = true);
Per altre informazioni sulle scadenze e l'annullamento RPC, vedere Reliable gRPC services with deadline and cancellation( Reliable gRPC services with deadline and cancellation).
Client denominati
In genere, un tipo di client gRPC viene registrato una volta e quindi inserito direttamente nel costruttore di un tipo da DI. Tuttavia, esistono scenari in cui è utile disporre di più configurazioni per un client. Ad esempio, un client che effettua chiamate gRPC con e senza autenticazione.
Più client con lo stesso tipo possono essere registrati assegnando a ogni client un nome. Ogni client denominato può avere una propria configurazione. Il metodo di estensione generico AddGrpcClient
include un overload che include un parametro name:
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();
});
Il codice precedente:
- Registra il
GreeterClient
tipo due volte, specificando un nome univoco per ogni oggetto. - Configura impostazioni diverse per ogni client denominato. La
GreeterAuthenticated
registrazione aggiunge le credenziali al canale in modo che le chiamate gRPC effettuate con esso siano autenticate.
Un client gRPC denominato viene creato nel codice dell'app usando GrpcClientFactory
. Il tipo e il nome del client desiderato viene specificato usando il metodo generico GrpcClientFactory.CreateClient
:
public class AggregatorService : Aggregator.AggregatorBase
{
private readonly Greeter.GreeterClient _client;
public AggregatorService(GrpcClientFactory grpcClientFactory)
{
_client = grpcClientFactory.CreateClient<Greeter.GreeterClient>("GreeterAuthenticated");
}
}
Risorse aggiuntive
L'integrazione di gRPC con HttpClientFactory
offre un modo centralizzato per creare client gRPC. Può essere usato come alternativa alla configurazione di istanze client gRPC autonome. L'integrazione della factory è disponibile nel pacchetto NuGet Grpc.Net.ClientFactory .
La factory offre i vantaggi seguenti:
- Fornisce una posizione centrale per la configurazione di istanze client gRPC logiche
- Gestisce la durata del sottostante
HttpClientMessageHandler
- Propagazione automatica della scadenza e dell'annullamento in un servizio gRPC ASP.NET Core
Registrare client gRPC
Per registrare un client gRPC, è possibile usare il metodo di estensione generico AddGrpcClient
all'interno di , specificando la classe client tipizzata gRPC e l'indirizzo Startup.ConfigureServices
del servizio:
services.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
});
Il tipo di client gRPC viene registrato come temporaneo con inserimento di dipendenze (DI). Il client può ora essere inserito e usato direttamente nei tipi creati da DI. ASP.NET Core controller MVC, SignalR hub e servizi gRPC sono posti in cui i client gRPC possono essere inseriti automaticamente:
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);
}
}
}
}
Configurare HttpHandler
HttpClientFactory
crea l'oggetto HttpMessageHandler
usato dal client gRPC. I metodi standard HttpClientFactory
possono essere usati per aggiungere middleware delle richieste in uscita o per configurare il sottostante HttpClientHandler
di HttpClient
:
services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.ConfigurePrimaryHttpMessageHandler(() =>
{
var handler = new HttpClientHandler();
handler.ClientCertificates.Add(LoadCertificate());
return handler;
});
Per altre informazioni, vedere Effettuare richieste HTTP usando IHttpClientFactory.
Configurare gli intercettori
Gli intercettori gRPC possono essere aggiunti ai client usando il AddInterceptor
metodo .
services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.AddInterceptor<LoggingInterceptor>();
Il codice precedente:
- Registra il
GreeterClient
tipo. - Configura un
LoggingInterceptor
oggetto per questo client.LoggingInterceptor
viene creato una volta e condiviso traGreeterClient
istanze.
Per impostazione predefinita, un intercettatore viene creato una volta e condiviso tra i client. Questo comportamento può essere sottoposto a override specificando un ambito durante la registrazione di un intercettatore. La factory client può essere configurata per creare un nuovo intercettatore per ogni client specificando InterceptorScope.Client
.
services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.AddInterceptor<LoggingInterceptor>(InterceptorScope.Client);
La creazione di intercettori con ambito client è utile quando un intercettatore richiede servizi con ambito o temporanei da DI.
È possibile usare un intercettatore gRPC o le credenziali del canale per inviare Authorization
metadati a ogni richiesta. Per altre informazioni sulla configurazione dell'autenticazione, vedere Inviare un token di connessione con gRPC client factory.
Configurare il canale
È possibile applicare una configurazione aggiuntiva a un canale usando il ConfigureChannel
metodo:
services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.ConfigureChannel(o =>
{
o.Credentials = new CustomCredentials();
});
ConfigureChannel
viene passata un'istanza GrpcChannelOptions
. Per altre informazioni, vedere Configurare le opzioni client.
Nota
Alcune proprietà vengono impostate su GrpcChannelOptions
prima dell'esecuzione del ConfigureChannel
callback:
HttpHandler
è impostato sul risultato da ConfigurePrimaryHttpMessageHandler.LoggerFactory
è impostato sul ILoggerFactory valore risolto da DI.
Questi valori possono essere sottoposti a override da ConfigureChannel
.
Propagazione della scadenza e dell'annullamento
I client gRPC creati dalla factory in un servizio gRPC possono essere configurati con EnableCallContextPropagation()
per propagare automaticamente la scadenza e il token di annullamento alle chiamate figlio. Il EnableCallContextPropagation()
metodo di estensione è disponibile nel pacchetto NuGet Grpc.AspNetCore.Server.ClientFactory .
La propagazione del contesto di chiamata funziona leggendo la scadenza e il token di annullamento dal contesto di richiesta gRPC corrente e propagandoli automaticamente alle chiamate in uscita effettuate dal client gRPC. La propagazione del contesto delle chiamate è un ottimo modo per garantire che gli scenari gRPC complessi annidati propagano sempre la scadenza e l'annullamento.
services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.EnableCallContextPropagation();
Per impostazione predefinita, EnableCallContextPropagation
genera un errore se il client viene usato all'esterno del contesto di una chiamata gRPC. L'errore è progettato per avvisare che non esiste un contesto di chiamata da propagare. Se si vuole usare il client all'esterno di un contesto di chiamata, eliminare l'errore quando il client è configurato con SuppressContextNotFoundErrors
:
services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.EnableCallContextPropagation(o => o.SuppressContextNotFoundErrors = true);
Per altre informazioni sulle scadenze e l'annullamento RPC, vedere Reliable gRPC services with deadline and cancellation( Reliable gRPC services with deadline and cancellation).
Client denominati
In genere, un tipo di client gRPC viene registrato una volta e quindi inserito direttamente nel costruttore di un tipo da DI. Tuttavia, esistono scenari in cui è utile disporre di più configurazioni per un client. Ad esempio, un client che effettua chiamate gRPC con e senza autenticazione.
Più client con lo stesso tipo possono essere registrati assegnando a ogni client un nome. Ogni client denominato può avere una propria configurazione. Il metodo di estensione generico AddGrpcClient
include un overload che include un parametro name:
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();
});
Il codice precedente:
- Registra il
GreeterClient
tipo due volte, specificando un nome univoco per ogni oggetto. - Configura impostazioni diverse per ogni client denominato. La
GreeterAuthenticated
registrazione aggiunge le credenziali al canale in modo che le chiamate gRPC effettuate con esso siano autenticate.
Un client gRPC denominato viene creato nel codice dell'app usando GrpcClientFactory
. Il tipo e il nome del client desiderato viene specificato usando il metodo generico GrpcClientFactory.CreateClient
:
public class AggregatorService : Aggregator.AggregatorBase
{
private readonly Greeter.GreeterClient _client;
public AggregatorService(GrpcClientFactory grpcClientFactory)
{
_client = grpcClientFactory.CreateClient<Greeter.GreeterClient>("GreeterAuthenticated");
}
}