Integracja fabryki klienta gRPC na platformie .NET
Uwaga
Nie jest to najnowsza wersja tego artykułu. Aby zapoznać się z bieżącą wersją, zobacz wersję tego artykułu platformy .NET 9.
Ważne
Te informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany, zanim zostanie wydany komercyjnie. Firma Microsoft nie udziela żadnych gwarancji, jawnych lub domniemanych, w odniesieniu do informacji podanych w tym miejscu.
Aby zapoznać się z bieżącą wersją, zobacz wersję tego artykułu platformy .NET 9.
Autor: James Newton-King
Integracja gRPC z usługą HttpClientFactory
oferuje scentralizowany sposób tworzenia klientów gRPC. Może służyć jako alternatywa do konfigurowania autonomicznych wystąpień klienta gRPC. Integracja z fabryką jest dostępna w pakiecie NuGet Grpc.Net.ClientFactory .
Fabryka oferuje następujące korzyści:
- Zapewnia centralną lokalizację konfigurowania logicznych wystąpień klienta gRPC.
- Zarządza okresem istnienia bazowego
HttpClientMessageHandler
obiektu . - Automatyczna propagacja terminu ostatecznego i anulowania w usłudze gRPC platformy ASP.NET Core.
Rejestrowanie klientów gRPC
Aby zarejestrować klienta gRPC, można użyć ogólnej AddGrpcClient
metody rozszerzenia w wystąpieniu WebApplicationBuilder punktu wejścia aplikacji w Program.cs
programie , określając typową klasę klienta i adres usługi gRPC:
builder.Services.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
});
Typ klienta gRPC jest zarejestrowany jako przejściowy z wstrzykiwania zależności (DI). Klient może być teraz wstrzykiwany i używany bezpośrednio w typach utworzonych przez di. ASP.NET podstawowych kontrolerów MVC, centrów i usług gRPC są miejscami, SignalR w których klienci gRPC mogą być automatycznie wstrzykiwani:
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);
}
}
}
}
Konfigurowanie programu HttpHandler
HttpClientFactory
tworzy element HttpMessageHandler
używany przez klienta gRPC. Metody standardowe HttpClientFactory
mogą służyć do dodawania oprogramowania pośredniczącego żądań wychodzących lub konfigurowania bazowego HttpClientHandler
elementu 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;
});
Aby uzyskać więcej informacji, zobacz Make HTTP requests using IHttpClientFactory (Żądania HTTP przy użyciu elementu IHttpClientFactory).
Konfigurowanie przechwytywania
Przechwytywanie gRPC można dodać do klientów przy użyciu AddInterceptor
metody .
builder.Services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.AddInterceptor<LoggingInterceptor>();
Powyższy kod ma następujące działanie:
- Rejestruje
GreeterClient
typ. - Konfiguruje
LoggingInterceptor
dla tego klienta.LoggingInterceptor
jest tworzony raz i współużytkowany między wystąpieniamiGreeterClient
.
Domyślnie przechwytujący jest tworzony raz i udostępniany między klientami. To zachowanie można zastąpić, określając zakres podczas rejestrowania przechwytywania. Fabrykę klienta można skonfigurować tak, aby utworzyć nowy moduł przechwytujący dla każdego klienta, określając wartość InterceptorScope.Client
.
builder.Services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.AddInterceptor<LoggingInterceptor>(InterceptorScope.Client);
Tworzenie przechwytujących o zakresie klienta jest przydatne, gdy przechwytywanie wymaga usług o określonym zakresie lub przejściowych z di.
Przechwytywanie gRPC lub poświadczeń kanału może służyć do wysyłania Authorization
metadanych z każdym żądaniem. Aby uzyskać więcej informacji na temat konfigurowania uwierzytelniania, zobacz Wysyłanie tokenu elementu nośnego za pomocą fabryki klienta gRPC.
Konfigurowanie kanału
Dodatkową konfigurację można zastosować do kanału ConfigureChannel
przy użyciu metody :
builder.Services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.ConfigureChannel(o =>
{
o.Credentials = new CustomCredentials();
});
ConfigureChannel
jest przekazywane GrpcChannelOptions
wystąpienie. Aby uzyskać więcej informacji, zobacz konfigurowanie opcji klienta.
Uwaga
Niektóre właściwości są ustawiane GrpcChannelOptions
przed uruchomieniem wywołania zwrotnego ConfigureChannel
:
HttpHandler
parametr jest ustawiony na wynik z ConfigurePrimaryHttpMessageHandler.LoggerFactory
parametr jest ustawiony na ILoggerFactory rozpoznany z di.
Te wartości można zastąpić za pomocą metody ConfigureChannel
.
Poświadczenia wywołań
Nagłówek uwierzytelniania można dodać do wywołań gRPC przy użyciu AddCallCredentials
metody :
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;
});
Aby uzyskać więcej informacji na temat konfigurowania poświadczeń wywołania, zobacz Token elementu nośnego z fabryką klienta gRPC.
Propagacja terminu ostatecznego i anulowania
Klienci gRPC utworzone przez fabrykę w usłudze gRPC można skonfigurować za pomocą polecenia , EnableCallContextPropagation()
aby automatycznie propagować ostateczny termin i token anulowania do wywołań podrzędnych. EnableCallContextPropagation()
Metoda rozszerzenia jest dostępna w pakiecie NuGet Grpc.AspNetCore.Server.ClientFactory.
Propagacja kontekstu wywołań działa przez odczytanie terminu ostatecznego i tokenu anulowania z bieżącego kontekstu żądania gRPC i automatyczne propagowanie ich do wywołań wychodzących wykonanych przez klienta gRPC. Propagacja kontekstu wywołań to doskonały sposób zapewnienia, że złożone, zagnieżdżone scenariusze gRPC zawsze propagują termin i anulowanie.
builder.Services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.EnableCallContextPropagation();
Domyślnie zgłasza błąd, EnableCallContextPropagation
jeśli klient jest używany poza kontekstem wywołania gRPC. Błąd jest przeznaczony do powiadamiania o tym, że nie ma kontekstu wywołania do propagacji. Jeśli chcesz użyć klienta poza kontekstem wywołania, pomiń błąd, gdy klient jest skonfigurowany za pomocą SuppressContextNotFoundErrors
polecenia :
builder.Services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.EnableCallContextPropagation(o => o.SuppressContextNotFoundErrors = true);
Aby uzyskać więcej informacji na temat terminów ostatecznych i anulowania RPC, zobacz Reliable gRPC services with deadline and cancellation (Niezawodne usługi gRPC z terminami i anulowaniem).
Nazwani klienci
Zazwyczaj typ klienta gRPC jest rejestrowany raz, a następnie wstrzykiwany bezpośrednio do konstruktora typu przez DI. Istnieją jednak scenariusze, w których warto mieć wiele konfiguracji dla jednego klienta. Na przykład klient, który wykonuje wywołania gRPC z uwierzytelnianiem i bez uwierzytelniania.
Wielu klientów o tym samym typie można zarejestrować, nadając każdemu klientowi nazwę. Każdy nazwany klient może mieć własną konfigurację. Metoda rozszerzenia ogólnego AddGrpcClient
ma przeciążenie, które zawiera parametr nazwy:
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();
});
Powyższy kod ma następujące działanie:
- Rejestruje
GreeterClient
typ dwa razy, określając unikatową nazwę dla każdego z nich. - Konfiguruje różne ustawienia dla każdego nazwanego klienta. Rejestracja
GreeterAuthenticated
dodaje poświadczenia do kanału, aby wywołania gRPC wykonane z nim zostały uwierzytelnione.
Nazwany klient gRPC jest tworzony w kodzie aplikacji przy użyciu polecenia GrpcClientFactory
. Typ i nazwa żądanego klienta jest określona przy użyciu metody ogólnej GrpcClientFactory.CreateClient
:
public class AggregatorService : Aggregator.AggregatorBase
{
private readonly Greeter.GreeterClient _client;
public AggregatorService(GrpcClientFactory grpcClientFactory)
{
_client = grpcClientFactory.CreateClient<Greeter.GreeterClient>("GreeterAuthenticated");
}
}
Dodatkowe zasoby
Integracja gRPC z usługą HttpClientFactory
oferuje scentralizowany sposób tworzenia klientów gRPC. Może służyć jako alternatywa do konfigurowania autonomicznych wystąpień klienta gRPC. Integracja z fabryką jest dostępna w pakiecie NuGet Grpc.Net.ClientFactory .
Fabryka oferuje następujące korzyści:
- Zapewnia centralną lokalizację do konfigurowania logicznych wystąpień klienta gRPC
- Zarządza okresem istnienia bazowego
HttpClientMessageHandler
- Automatyczna propagacja terminu ostatecznego i anulowania w usłudze gRPC platformy ASP.NET Core
Rejestrowanie klientów gRPC
Aby zarejestrować klienta gRPC, AddGrpcClient
można użyć ogólnej metody rozszerzenia w programie Startup.ConfigureServices
, określając typową klasę klienta i adres usługi gRPC:
services.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
});
Typ klienta gRPC jest zarejestrowany jako przejściowy z wstrzykiwania zależności (DI). Klient może być teraz wstrzykiwany i używany bezpośrednio w typach utworzonych przez di. ASP.NET podstawowych kontrolerów MVC, centrów i usług gRPC są miejscami, SignalR w których klienci gRPC mogą być automatycznie wstrzykiwani:
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);
}
}
}
}
Konfigurowanie programu HttpHandler
HttpClientFactory
tworzy element HttpMessageHandler
używany przez klienta gRPC. Metody standardowe HttpClientFactory
mogą służyć do dodawania oprogramowania pośredniczącego żądań wychodzących lub konfigurowania bazowego HttpClientHandler
elementu HttpClient
:
services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.ConfigurePrimaryHttpMessageHandler(() =>
{
var handler = new HttpClientHandler();
handler.ClientCertificates.Add(LoadCertificate());
return handler;
});
Aby uzyskać więcej informacji, zobacz Make HTTP requests using IHttpClientFactory (Żądania HTTP przy użyciu elementu IHttpClientFactory).
Konfigurowanie przechwytywania
Przechwytywanie gRPC można dodać do klientów przy użyciu AddInterceptor
metody .
services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.AddInterceptor<LoggingInterceptor>();
Powyższy kod ma następujące działanie:
- Rejestruje
GreeterClient
typ. - Konfiguruje
LoggingInterceptor
dla tego klienta.LoggingInterceptor
jest tworzony raz i współużytkowany między wystąpieniamiGreeterClient
.
Domyślnie przechwytujący jest tworzony raz i udostępniany między klientami. To zachowanie można zastąpić, określając zakres podczas rejestrowania przechwytywania. Fabrykę klienta można skonfigurować tak, aby utworzyć nowy moduł przechwytujący dla każdego klienta, określając wartość InterceptorScope.Client
.
services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.AddInterceptor<LoggingInterceptor>(InterceptorScope.Client);
Tworzenie przechwytujących o zakresie klienta jest przydatne, gdy przechwytywanie wymaga usług o określonym zakresie lub przejściowych z di.
Przechwytywanie gRPC lub poświadczeń kanału może służyć do wysyłania Authorization
metadanych z każdym żądaniem. Aby uzyskać więcej informacji na temat konfigurowania uwierzytelniania, zobacz Wysyłanie tokenu elementu nośnego za pomocą fabryki klienta gRPC.
Konfigurowanie kanału
Dodatkową konfigurację można zastosować do kanału ConfigureChannel
przy użyciu metody :
services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.ConfigureChannel(o =>
{
o.Credentials = new CustomCredentials();
});
ConfigureChannel
jest przekazywane GrpcChannelOptions
wystąpienie. Aby uzyskać więcej informacji, zobacz konfigurowanie opcji klienta.
Uwaga
Niektóre właściwości są ustawiane GrpcChannelOptions
przed uruchomieniem wywołania zwrotnego ConfigureChannel
:
HttpHandler
parametr jest ustawiony na wynik z ConfigurePrimaryHttpMessageHandler.LoggerFactory
parametr jest ustawiony na ILoggerFactory rozpoznany z di.
Te wartości można zastąpić za pomocą metody ConfigureChannel
.
Propagacja terminu ostatecznego i anulowania
Klienci gRPC utworzone przez fabrykę w usłudze gRPC można skonfigurować za pomocą polecenia , EnableCallContextPropagation()
aby automatycznie propagować ostateczny termin i token anulowania do wywołań podrzędnych. EnableCallContextPropagation()
Metoda rozszerzenia jest dostępna w pakiecie NuGet Grpc.AspNetCore.Server.ClientFactory.
Propagacja kontekstu wywołań działa przez odczytanie terminu ostatecznego i tokenu anulowania z bieżącego kontekstu żądania gRPC i automatyczne propagowanie ich do wywołań wychodzących wykonanych przez klienta gRPC. Propagacja kontekstu wywołań to doskonały sposób zapewnienia, że złożone, zagnieżdżone scenariusze gRPC zawsze propagują termin i anulowanie.
services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.EnableCallContextPropagation();
Domyślnie zgłasza błąd, EnableCallContextPropagation
jeśli klient jest używany poza kontekstem wywołania gRPC. Błąd jest przeznaczony do powiadamiania o tym, że nie ma kontekstu wywołania do propagacji. Jeśli chcesz użyć klienta poza kontekstem wywołania, pomiń błąd, gdy klient jest skonfigurowany za pomocą SuppressContextNotFoundErrors
polecenia :
services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.EnableCallContextPropagation(o => o.SuppressContextNotFoundErrors = true);
Aby uzyskać więcej informacji na temat terminów ostatecznych i anulowania RPC, zobacz Reliable gRPC services with deadline and cancellation (Niezawodne usługi gRPC z terminami i anulowaniem).
Nazwani klienci
Zazwyczaj typ klienta gRPC jest rejestrowany raz, a następnie wstrzykiwany bezpośrednio do konstruktora typu przez DI. Istnieją jednak scenariusze, w których warto mieć wiele konfiguracji dla jednego klienta. Na przykład klient, który wykonuje wywołania gRPC z uwierzytelnianiem i bez uwierzytelniania.
Wielu klientów o tym samym typie można zarejestrować, nadając każdemu klientowi nazwę. Każdy nazwany klient może mieć własną konfigurację. Metoda rozszerzenia ogólnego AddGrpcClient
ma przeciążenie, które zawiera parametr nazwy:
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();
});
Powyższy kod ma następujące działanie:
- Rejestruje
GreeterClient
typ dwa razy, określając unikatową nazwę dla każdego z nich. - Konfiguruje różne ustawienia dla każdego nazwanego klienta. Rejestracja
GreeterAuthenticated
dodaje poświadczenia do kanału, aby wywołania gRPC wykonane z nim zostały uwierzytelnione.
Nazwany klient gRPC jest tworzony w kodzie aplikacji przy użyciu polecenia GrpcClientFactory
. Typ i nazwa żądanego klienta jest określona przy użyciu metody ogólnej GrpcClientFactory.CreateClient
:
public class AggregatorService : Aggregator.AggregatorBase
{
private readonly Greeter.GreeterClient _client;
public AggregatorService(GrpcClientFactory grpcClientFactory)
{
_client = grpcClientFactory.CreateClient<Greeter.GreeterClient>("GreeterAuthenticated");
}
}