[C#] .NET의 gRPC 인터셉터 - 클라이언트 측 인터셉터
- gRPC
- 2022. 4. 27. 18:00
참고
Interceptor 란?
- 인터셉터는 앱이 들어오는 또는 나가는 gRPC 호출과 상호 작용할 수 있도록 하는 gRPC 개념으로, 요청 처리 파이프라인을 보강하는 방법을 제공합니다.
- 인터셉터는 채널 또는 서비스에 대해 구성되고 각 gRPC 호출에서 자동으로 실행됩니다.
- 인터셉터는 사용자의 애플리케이션 논리에 투명하므로 로깅, 모니터링, 인증, 유효성 검사와 같은 공통 사례에 적합한 솔루션입니다.
Interceptor 형식
Interceptor
형식에서 상속되는 클래스를 만들어 gRPC 서버 및 클라이언트 모두에 대해 인터셉터를 구현할 수 있습니다.
public class ExampleInterceptor : Interceptor
{
}
- 기본적으로,
Interceptor
기본 클래스는 아무 동작도 하지 않습니다. - 인터셉터 구현에서 적절한 기본 클래스 메서드를 재정의 하여 인터셉터에 동작을 추가합니다.
gRPC 인터셉터 프로젝트 만들기
- 실제로 예제 코드를 작성하여 인터셉터에 대한 이해를 높여 보도록 하겠습니다.
- gRPC 예제 코드는 C# 프로젝트로 작성할 것이고, Server/Client 작성해 보겠습니다.
클라이언트 측 인터셉터 작성
- gRPC 클라이언트 인터셉터는 나가는 RPC 호출을 가로챌 수 있습니다.
- 전송된 요청, 등어오는 응답 및 클라이언트 쪽 호출의 컨텍스트에 대한 액세스를 제공합니다.
- 클라이언트에 대해 재정의할
Interceptor
메서드 :BlockingUnaryCall
: 단항 RPC의 차단 호출을 가로챕니다.AsyncUnaryCall
: 단항 RPC의 비동기 호출을 가로챕니다.AsyncClientStreamCall
: 클라이언트 스트리밍 RPC의 비동기 호출을 가로챕니다.AsyncServerStreamCall
: 서버 스트리밍 RPC 의 비동기 호출을 가로챕니다.AsyncDuplexStreamingCall
: 양방향 스트리밍 RPC의 비동기 호출을 가로챕니다.
BlockingUnaryCall
및AsyncUnaryCall
모두 단항 RPC 를 참조하지만 서로 교환하여 사용할 수는 없습니다. 차단 호출은AsyncUnaryCall
에서 가로채지 않고, 비동기 호출은BlockingUnaryCall
에서 가로채지 않습니다.
- 그럼
ASP.NET Core gRPC 서비스
프로젝트 하나를 생성 후, 인터셉터 내용을 작성해 보겠습니다.
gRPC 서비스 프로젝트 생성
- Visual Studio 2022 를 실행 후,
ASP.NET Core gRPC 서비스
프로젝트를 생성 합니다. - 해당 프로젝트가 생성 되면, gRPC 서버가 생성된 것입니다.
클라이언트 gRPC 인터셉터 만들기
- gRPC 서버 생성이 완료 되었다면, 콘솔 프로젝트 하나를 생성한 후 gRPC 클라이언트 인터셉터 클래스를 생성합니다.
- 인터셉터 이름은
ClientLoggingInterceptor
이라고 정의하였고, 코드 내용은 아래와 같습니다.
using Grpc.Core;
using Grpc.Core.Interceptors;
using Microsoft.Extensions.Logging;
namespace Client.Interceptors
{
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: {context.Method.Type}. " +
$"Method: {context.Method.Name}.");
return continuation(request, context);
}
}
}
AsyncUnaryCall 재정의 :
- 비동기 단항 호출을 가로챕니다.
- 호출 세부 정보를 로깅합니다.
- 메서드에 전달된
continuation
매개 변수를 호출합니다. 마지막 인터셉터인 경우 체인의 다음 인터셉터 또는 기본 호출 호출자를 호출합니다.
- 각 서비스 메서드 종류의
Interceptor
에 대한 메서드에는 서로 다른 서명이 있습니다. - 그러나
continuation
및context
의 개념과 매개 변수는 동일하게 유지됩니다.continuation
는 체인의 다음 인터셉터 또는 기본 호출 호출자를 호출하는 대리자입니다.- 한번도 호출하지 않거나 여러 번 호출하는 것은 오류가 아닙니다. 인터셉터는
continuation
대리자에서 반환된 호출 표현을 반환할 필요가 없습니다. - 대리자 호출을 생략하고 고유한 호출 표현 인스턴스를 반환하면 인터셉터 체인이 끊어지고 응답이 즉시 반환됩니다.
context
는 클라이언트 쪽 호출과 연결된 범위가 지정된 값을 전달합니다.context
는 보안 주체, 자격 증명 또는 추적 데이터와 같은 메타데이터를 전달하는 데 사용합니다.- 또한
context
는 최종 기한 및 취소에 대한 정보를 전달합니다.
클라이언트 인터셉터 구성하기
- 앞서
ClientLoggingInterceptor
인터셉터 하나를 생성하였습니다. - 다음으로 gRPC 클라이언트 인터셉터를 채널에서 구성해야 합니다.
- 구성 방법은 다음과 같습니다.
GrpcChannel.ForAddress
를 사용하여 태널을 만듭니다.Intercept
확장 메서드를 사용하여 인터셉터를 사용하도록 채널을 구성합니다.- 이 메서드는
CallInvoker
를 반환합니다. 강력한 형식의 gRPC 클라이언트는 채널과 마찬가지로 호출자에게 만들 수 있습니다. - 호출자에서 클라이언트를 만듭니다. 클라이언트에서 수행한 gRPC 호출은 인터셉터를 자동으로 실행합니다.
using Client.Interceptors;
using Grpc.Core.Interceptors;
using Grpc.Net.Client;
using gRPCInterceptorSample;
using Microsoft.Extensions.Logging;
var loggerFactory = LoggerFactory.Create(logging =>
{
logging.SetMinimumLevel(LogLevel.Debug);
});
using var channel = GrpcChannel.ForAddress("https://localhost:7081", new GrpcChannelOptions { LoggerFactory = loggerFactory });
var invoker = channel.Intercept(new ClientLoggingInterceptor(loggerFactory));
var client = new Greeter.GreeterClient(invoker);
var reply = await client.SayHelloAsync(
new HelloRequest { Name = "Beom" }
);
Console.WriteLine($"Greeting {reply.Message}");
실행 결과
- 실행 결과, Client 가 Server 로 RPC 메시지를 보낼 때
ClientLoggingInterceptor
인터셉터가 먼저 요청 메시지를 가로채고, 로그가 찍히는 것을 확인할 수 있습니다.
Starting call. Type: Unary. Method: SayHello.
728x90
'gRPC' 카테고리의 다른 글
[gRPC] gRPC C# Server/Client 예제 (0) | 2023.02.26 |
---|---|
[C#] .NET FileUpload gPRC Service Poc (0) | 2023.02.02 |
[C#] .NET의 gRPC 서버 측 인터셉터 (0) | 2022.04.22 |
[gRPC] gRPC 프로토콜 버퍼란? (0) | 2022.03.17 |
[gRPC] gRPC 장점 (0) | 2022.03.17 |
이 글을 공유하기