ASP.NET Core 3.0 gRPC拦截器的使用代码示例

作者:袖梨 2022-06-25

本篇文章小编给大家分享一下ASP.NET Core 3.0 gRPC拦截器的使用代码示例,小编觉得挺不错的,现在分享给大家供大家参考,有需要的小伙伴们可以来看看。

拦截器就像MVC的过滤器或者是ASP.NET Core middleware 一样,具有面向切面的思想,可以在调用服务的时候进行一些统一处理, 很适合在这里处理验证、日志等流程。

二. Interceptor 类介绍

Interceptor类是gRPC服务拦截器的基类,是一个抽象类,它定了几个虚方法,分别如下:

public virtual TResponse BlockingUnaryCall();
public virtual AsyncUnaryCall AsyncUnaryCall();
public virtual AsyncServerStreamingCall AsyncServerStreamingCall();
public virtual AsyncClientStreamingCall AsyncClientStreamingCall();
public virtual AsyncDuplexStreamingCall AsyncDuplexStreamingCall();
public virtual Task UnaryServerHandler();
public virtual Task ClientStreamingServerHandler();
public virtual Task ServerStreamingServerHandler();
public virtual Task DuplexStreamingServerHandler();

各个方法作用如下:

三. 客户端拦截器在实际使用中,可以根据自己的需要来使用对应的拦截方法。

基于前面两篇文章使用的Demo。

在客户端项目新建一个类,命名为ClientLoggerInterceptor,继承拦截器基类Interceptor。

我们在前面使用的Demo,定义了撸猫服务,其中SuckingCatAsync方法为异步调用,所以我们重写拦截器的AsyncUnaryCall方法

public class ClientLoggerInterceptor:Interceptor
{
  public override AsyncUnaryCall AsyncUnaryCall(
    TRequest request,
    ClientInterceptorContext context,
    AsyncUnaryCallContinuation continuation)
  {
    LogCall(context.Method);

    return continuation(request, context);
  }

  private void LogCall(Method method)
    where TRequest : class
    where TResponse : class
  {
    var initialColor = Console.ForegroundColor;
    Console.ForegroundColor = ConsoleColor.Green;
    Console.WriteLine($"Starting call. Type: {method.Type}. Request: {typeof(TRequest)}. Response: {typeof(TResponse)}");
    Console.ForegroundColor = initialColor;
  }
}

注册拦截器:

var channel = GrpcChannel.ForAddress("https://localhost:5001");
var invoker = channel.Intercept(new ClientLoggerInterceptor());
var catClient = new LuCat.LuCatClient(invoker);
var catReply = await catClient.SuckingCatAsync(new Empty());
Console.WriteLine("调用撸猫服务:"+ catReply.Message);

然后运行:

可以看到成功的在客户端拦截到了调用,并记录了调用信息。

四. 服务端拦截器

在服务端项目新建一个类,命名为ServerLoggerInterceptor,继承拦截器基类Interceptor。

我们在服务端需要实现的方法是UnaryServerHandler

public class ServerLoggerInterceptor: Interceptor
{
  private readonly ILogger _logger;

  public ServerLoggerInterceptor(ILogger logger)
  {
    _logger = logger;
  }

  public override Task UnaryServerHandler(
    TRequest request,
    ServerCallContext context,
    UnaryServerMethod continuation)
  {
    LogCall(MethodType.Unary, context);
    return continuation(request, context);
  }

  private void LogCall(MethodType methodType, ServerCallContext context)
    where TRequest : class
    where TResponse : class
  {
    _logger.LogWarning($"Starting call. Type: {methodType}. Request: {typeof(TRequest)}. Response: {typeof(TResponse)}");
  }
}

注册拦截器:

public void ConfigureServices(IServiceCollection services)
{
  services.AddGrpc(options =>
  {
    options.Interceptors.Add();
  });
}

运行:

可以看到服务端成功拦截到了,客户端的调用。

相关文章

精彩推荐