iT邦幫忙

2025 iThome 鐵人賽

DAY 13
1
Software Development

30 天的 .Net gRPC 迷途系列 第 13

Day13 gRPC 攔截器(Interceptor)

  • 分享至 

  • xImage
  •  

查了一下,在 .Net 的 gRPC 服務裡面沒有像是 Filter/Middleware 這樣的功能

用了另外一個攔截器的方式,今天就對這功能做一些介紹

.Net 的攔截器提供了以下幾種(取自微軟官方)

  • BlockingUnaryCall:攔截一元 RPC 的封鎖調用。
  • AsyncUnaryCall:攔截一元 RPC 的非同步叫用。
  • AsyncClientStreamingCall:攔截用戶端串流 RPC 的非同步叫用。
  • AsyncServerStreamingCall:攔截伺服器串流 RPC 的非同步調用。
  • AsyncDuplexStreamingCall:攔截雙向串流 RPC 的非同步叫用。

BlockingUnaryCall 一元同步攔截器

這個攔截器的用法網路上查,其實是在 Client 端使用。應用在一些腳本、一次性執行...等,不需要非同步的情境裡面

var greeterClient = new Greeter.GreeterClient(channel);

var helloRes = greeterClient.SayHello(new HelloRequest { Name = user });

AsyncUnaryCall 一元非同步攔截器

以下用一個 Logging 的情境介紹

新增一個 LoggingInterceptor.cs

// 新增併繼承 Interceptor
public class LoggingInterceptor : Interceptor
{
    private readonly ILogger<LoggingInterceptor> _logger;

    public LoggingInterceptor(ILogger<LoggingInterceptor> logger)
    {
        _logger = logger;
    }
    // 選擇要覆寫的攔截器
    public override async Task<TResponse> UnaryServerHandler<TRequest, TResponse>(
        TRequest request,
        ServerCallContext context,
        UnaryServerMethod<TRequest, TResponse> continuation)
    {
        _logger.LogInformation("gRPC 請求開始: {Method}", context.Method);

        try
        {
            var response = await continuation(request, context);
            _logger.LogInformation("gRPC 請求完成: {Method}", context.Method);
            return response;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "gRPC 請求發生錯誤: {Method}", context.Method);
            throw;
        }
    }

    // 你也可以覆寫其他方法,如:
    // - ClientStreamingServerHandler
    // - ServerStreamingServerHandler
    // - DuplexStreamingServerHandler
}

Server 端

Program.cs 內記得註冊這個攔截器

builder.Services
    .AddGrpc(options =>
    {
        options.Interceptors.Add<LoggingInterceptor>();
        // 或使用實例:options.Interceptors.Add(new LoggingInterceptor(...));
    });
    
// or 針對特定的 Service 註冊
app.MapGrpcService<MyGrpcService>()
   .AddInterceptor<LoggingInterceptor>();

Client 端

在 Client 端也可以使用攔截器

var invoker = channel.Intercept(new LoggingInterceptor(logger));

var client = new MyService.MyServiceClient(invoker);

上一篇
Day12 gRPC 驗證及授權
系列文
30 天的 .Net gRPC 迷途13
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言