查了一下,在 .Net 的 gRPC 服務裡面沒有像是 Filter/Middleware 這樣的功能
用了另外一個攔截器的方式,今天就對這功能做一些介紹
.Net 的攔截器提供了以下幾種(取自微軟官方)
這個攔截器的用法網路上查,其實是在 Client 端使用。應用在一些腳本、一次性執行...等,不需要非同步的情境裡面
var greeterClient = new Greeter.GreeterClient(channel);
var helloRes = greeterClient.SayHello(new HelloRequest { Name = user });
以下用一個 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
}
Program.cs
內記得註冊這個攔截器
builder.Services
.AddGrpc(options =>
{
options.Interceptors.Add<LoggingInterceptor>();
// 或使用實例:options.Interceptors.Add(new LoggingInterceptor(...));
});
// or 針對特定的 Service 註冊
app.MapGrpcService<MyGrpcService>()
.AddInterceptor<LoggingInterceptor>();
在 Client 端也可以使用攔截器
var invoker = channel.Intercept(new LoggingInterceptor(logger));
var client = new MyService.MyServiceClient(invoker);