Poznámka
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Poznámka:
Toto není nejnovější verze tohoto článku. Aktuální vydání tohoto článku najdete ve verzi .NET 9.
Varování
Tato verze ASP.NET Core se už nepodporuje. Další informace najdete v zásadách podpory .NET a .NET Core. Aktuální vydání tohoto článku najdete ve verzi .NET 9.
Důležité
Tyto informace se týkají předběžného vydání produktu, který může být podstatně změněn před komerčním vydáním. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.
Aktuální vydání tohoto článku najdete ve verzi .NET 9.
Autor: Ernst Nguyen
Průsečíky jsou koncept gRPC, který umožňuje aplikacím pracovat s příchozími nebo odchozími voláními gRPC. Nabízejí způsob, jak rozšířit kanál zpracování požadavků.
Průsečíky jsou nakonfigurované pro kanál nebo službu a spouští se automaticky pro každé volání gRPC. Vzhledem k tomu, že zachytávače jsou pro logiku aplikace uživatele transparentní, představují vynikající řešení pro běžné případy, jako je protokolování, monitorování, ověřování a validace.
Typ Interceptor
Zachytávače lze implementovat pro servery gRPC i klienty tím, že vytvoříte třídu, která dědí z typu Interceptor
.
public class ExampleInterceptor : Interceptor
{
}
Ve výchozím nastavení Interceptor
základní třída nic nedělá. Přidejte chování do zachytávače přepsáním odpovídajících metod základní třídy v implementaci zachytávače.
Klientské interceptory
Zachycovače klienta gRPC zachycují odchozí volání RPC. Poskytují přístup k odeslané žádosti, příchozí odpovědi a kontextu pro volání na straně klienta.
Interceptor
metody, které je třeba přepsat pro klienta:
-
BlockingUnaryCall
: Zachytí blokující vyvolání unárního RPC. -
AsyncUnaryCall
: Zachycuje asynchronní vyvolání unárního RPC. -
AsyncClientStreamingCall
: Zachytí asynchronní volání RPC klientského streamování. -
AsyncServerStreamingCall
: Zachytí asynchronní vyvolání streamování RPC ze serveru. -
AsyncDuplexStreamingCall
: Zachytí asynchronní vyvolání obousměrného streamování RPC.
Varování
I když obě BlockingUnaryCall
a AsyncUnaryCall
odkazují na unární rpcs, nejsou zaměnitelné. Blokující vyvolání není zachyceno AsyncUnaryCall
a asynchronní vyvolání není zachyceno BlockingUnaryCall
.
Vytvoření zachytávání gRPC klienta
Následující kód představuje základní příklad zachycení asynchronního vyvolání unárního volání:
public class ClientLoggingInterceptor : Interceptor
{
private readonly ILogger _logger;
public ClientLoggingInterceptor(ILoggerFactory loggerFactory)
{
_logger = loggerFactory.CreateLogger<ClientLoggingInterceptor>();
}
public override AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(
TRequest request,
ClientInterceptorContext<TRequest, TResponse> context,
AsyncUnaryCallContinuation<TRequest, TResponse> continuation)
{
_logger.LogInformation("Starting call. Type/Method: {Type} / {Method}",
context.Method.Type, context.Method.Name);
return continuation(request, context);
}
}
Přepsání AsyncUnaryCall
:
- Zachycuje asynchronní unární volání.
- Zaznamenává podrobnosti o hovoru.
- Volá parametr předaný
continuation
do metody. Tím se vyvolá další zachytávač v sérii nebo podkladový volací vyvolávač, pokud se jedná o poslední zachytávač.
Metody na Interceptor
pro každý druh metody službou mají různé signatury. Koncept a continuation
context
parametry však zůstávají stejné:
-
continuation
je delegát, který vyvolá další interceptor v řetězu nebo základní volací mechanismus (pokud v řetězci nezůstal žádný interceptor). Nejedná se o chybu, která by ji volala nulou nebo vícekrát. Interceptory nejsou povinny vracet reprezentaci volání (AsyncUnaryCall
v případě unárního RPC), kterou vrátí delegátcontinuation
. Vynechání volání delegáta a vrácení vaší vlastní instance reprezentace volání přeruší řetězec přerušovačů a okamžitě vrátí přidruženou odpověď. -
context
nese vymezené hodnoty spojené s voláním na straně klienta. Použijtecontext
k předávání metadat, jako jsou bezpečnostní prvky, přihlašovací údaje nebo sledovací data. Kromě tohocontext
přináší informace o konečných termínech a zrušení. Další informace najdete v tématu Spolehlivé služby gRPC s termíny a zrušením.
Čekání na odpověď v zachytávání klienta
Zachytávač může čekat na odpověď v unárních a klientských streamovacích voláních aktualizováním hodnoty AsyncUnaryCall<TResponse>.ResponseAsync
nebo AsyncClientStreamingCall<TRequest, TResponse>.ResponseAsync
.
public class ErrorHandlerInterceptor : Interceptor
{
public override AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(
TRequest request,
ClientInterceptorContext<TRequest, TResponse> context,
AsyncUnaryCallContinuation<TRequest, TResponse> continuation)
{
var call = continuation(request, context);
return new AsyncUnaryCall<TResponse>(
HandleResponse(call.ResponseAsync),
call.ResponseHeadersAsync,
call.GetStatus,
call.GetTrailers,
call.Dispose);
}
private async Task<TResponse> HandleResponse<TResponse>(Task<TResponse> inner)
{
try
{
return await inner;
}
catch (Exception ex)
{
throw new InvalidOperationException("Custom error", ex);
}
}
}
Předchozí kód:
- Vytvoří nový interceptor, který přepisuje
AsyncUnaryCall
. - Přepsání
AsyncUnaryCall
:- Zavolá parametr
continuation
, který vyvolá další položku v řetězci zachytávače. - Vytvoří novou
AsyncUnaryCall<TResponse>
instanci na základě výsledku pokračování. - Zabalí
ResponseAsync
úlohu pomocíHandleResponse
metody. - Čeká na odpověď s
HandleResponse
. Čekání na odpověď umožní přidání logiky po přijetí odpovědi klientem. Čekáním na odpověď v bloku try-catch je možné zaprotokolovat chyby volání.
- Zavolá parametr
Další informace o tom, jak vytvořit zachycovač klienta, najdete ClientLoggerInterceptor.cs
v příkladu grpc/grpc-dotnet
v úložišti GitHub.
Konfigurace klientských interceptorů
Průsečíky klienta gRPC se konfigurují v kanálu.
Následující kód:
- Vytvoří kanál pomocí
GrpcChannel.ForAddress
. -
Intercept
Pomocí metody rozšíření nakonfiguruje kanál tak, aby používal průsečík. Všimněte si, že tato metoda vrátíCallInvoker
. Silně typovaní klienti gRPC mohou být vytvořeni z invokeru stejně jako z kanálu. - Vytvoří klienta z invokeru. Volání gRPC provedená klientem automaticky spustí průsečík.
using var channel = GrpcChannel.ForAddress("https://localhost:5001");
var invoker = channel.Intercept(new ClientLoggerInterceptor());
var client = new Greeter.GreeterClient(invoker);
Metodu Intercept
rozšíření je možné zřetězit a nakonfigurovat více průsečíků pro kanál. Alternativně existuje Intercept
přetížení, které přijímá více průsečíků. Libovolný počet průsečíků lze spustit pro jedno volání gRPC, jak ukazuje následující příklad:
var invoker = channel
.Intercept(new ClientTokenInterceptor())
.Intercept(new ClientMonitoringInterceptor())
.Intercept(new ClientLoggerInterceptor());
Průsečíky se vyvolávají v obráceném pořadí zřetězených Intercept
rozšiřujících metod. V předchozím kódu jsou interceptory vyvolány v následujícím pořadí:
ClientLoggerInterceptor
ClientMonitoringInterceptor
ClientTokenInterceptor
Informace o konfiguraci průsečíků s klientskou továrnou gRPC najdete v tématu integrace klientské továrny gRPC v .NET.
Zachytávání serverů
Interceptory serveru gRPC interceptují příchozí požadavky RPC. Poskytují přístup k příchozímu požadavku, odchozí odpovědi a kontextu volání na straně serveru.
Interceptor
metody přepsání pro server:
-
UnaryServerHandler
: Zachytí unární RPC. -
ClientStreamingServerHandler
: Zachytí rpc streamování klienta. -
ServerStreamingServerHandler
: Zachytí protokol RPC streamování serveru. -
DuplexStreamingServerHandler
: Zachytí obousměrné streamování RPC.
Vytvořte přerušovač gRPC serveru
Následující kód představuje příklad zachycení příchozího unárního RPC:
public class ServerLoggerInterceptor : Interceptor
{
private readonly ILogger _logger;
public ServerLoggerInterceptor(ILogger<ServerLoggerInterceptor> logger)
{
_logger = logger;
}
public override async Task<TResponse> UnaryServerHandler<TRequest, TResponse>(
TRequest request,
ServerCallContext context,
UnaryServerMethod<TRequest, TResponse> continuation)
{
_logger.LogInformation("Starting receiving call. Type/Method: {Type} / {Method}",
MethodType.Unary, context.Method);
try
{
return await continuation(request, context);
}
catch (Exception ex)
{
_logger.LogError(ex, $"Error thrown by {context.Method}.");
throw;
}
}
}
Přepsání UnaryServerHandler
:
- Zachytí příchozí unární hovor.
- Zaznamenává podrobnosti o hovoru.
- Volá parametr předaný
continuation
do metody. Tím se vyvolá další přerušovač v řetězci nebo obslužný modul služby, pokud je toto poslední přerušovač. - Zaznamená všechny výjimky. Čekání na pokračování umožní přidání logiky po spuštění metody služby. Čekáním na pokračování v bloku try-catch je možné protokolovat chyby z metod.
Podpis metod průsečíků klienta i serveru je podobný:
-
continuation
je zkratka pro delegáta příchozího RPC volání dalšího průsečíku v řetězu nebo obslužné rutině služby (pokud v řetězu není ponechán žádný průsečík). Podobně jako u zachytávačů klienta ji můžete kdykoli zavolat a nemusíte vracet odpověď přímo od delegáta pro pokračování. Odchozí logiku lze přidat po provedení obslužné rutiny služby tím, že vyčkáme na pokračování. -
context
nese metadata spojená s voláním na straně serveru, jako jsou metadata požadavku, termíny a zrušení nebo výsledek RPC.
Další informace o tom, jak vytvořit zachycovač serveru, najdete ServerLoggerInterceptor.cs
v příkladu grpc/grpc-dotnet
v úložišti GitHub.
Konfigurace serverových interceptorů
Přerušovače serverů gRPC jsou konfigurovány při spuštění. Následující kód:
- Přidá gRPC do aplikace pomocí
AddGrpc
. - Konfiguruje
ServerLoggerInterceptor
pro všechny služby tak, že ji přidáte do kolekce možnostíInterceptors
služby.
public void ConfigureServices(IServiceCollection services)
{
services.AddGrpc(options =>
{
options.Interceptors.Add<ServerLoggerInterceptor>();
});
}
Zachytávání lze také nakonfigurovat pro konkrétní službu pomocí AddServiceOptions
a určení typu služby.
public void ConfigureServices(IServiceCollection services)
{
services
.AddGrpc()
.AddServiceOptions<GreeterService>(options =>
{
options.Interceptors.Add<ServerLoggerInterceptor>();
});
}
Zachytávače se spouštějí v pořadí, v jakém jsou přidány do InterceptorCollection
. Pokud jsou nakonfigurovány jak globální, tak zachytávače pro jednotlivou službu, spustí se nejprve globálně nakonfigurované zachytávače, a teprve poté ty pro jednotlivou službu.
Ve výchozím nastavení mají průsečíky serverů gRPC životnost podle požadavku. Přepsání tohoto chování je možné prostřednictvím registrace typu interceptor pomocí injekce závislostí. Následující příklad zaregistruje životnost jednohotonu ServerLoggerInterceptor
:
public void ConfigureServices(IServiceCollection services)
{
services.AddGrpc(options =>
{
options.Interceptors.Add<ServerLoggerInterceptor>();
});
services.AddSingleton<ServerLoggerInterceptor>();
}
Zachytávače gRPC versus middleware
ASP.NET middleware Core nabízí podobné funkce v porovnání s průsečíky v aplikacích GRPC založených na jádru C. Middleware a zachytávače v ASP.NET Core jsou koncepčně podobné. Oba:
- Slouží k vytvoření potrubí, které zpracovává požadavek gRPC.
- Povolte provedení práce před nebo po další komponentě v procesním řetězci.
- Poskytnout přístup k
HttpContext
:- V middlewaru je parametr
HttpContext
. - U zachytávačů
HttpContext
lze přistupovat pomocí parametruServerCallContext
s rozšiřovací metodouServerCallContext.GetHttpContext
. Tato funkce je specifická pro průsečíky spuštěné v ASP.NET Core.
- V middlewaru je parametr
Rozdíly průsečíku gRPC od middlewaru ASP.NET Core:
- Průsečíky:
- Pracovat s gRPC vrstvy abstrakce pomocí
ServerCallContext
. - Poskytnutí přístupu k:
- Deserializovaná zpráva byla odeslána volání.
- Zpráva vrácená z volání předtím, než byla serializována.
- Dokáže zachytit a zpracovat výjimky vyvolané službami gRPC.
- Pracovat s gRPC vrstvy abstrakce pomocí
- Middleware:
- Spustí se pro všechny požadavky HTTP.
- Spustí se před průsečíky gRPC.
- Pracuje s podkladovými zprávami HTTP/2.
- Může přistupovat pouze k bajtům z datových proudů požadavků a odpovědí.