一. 前言
前面两篇文章给大家介绍了使用gRPC的入门以及双向流的使用,今天介绍的是gRPC中的拦截器。拦截器就像MVC的过滤器或者是ASP.NET Core middleware 一样,具有面向切面的思想,可以在调用服务的时候进行一些统一处理, 很适合在这里处理验证、日志等流程。本片文章就以记录日志为例来进行讲解。
二. Interceptor 类介绍
Interceptor类是gRPC服务拦截器的基类,是一个抽象类,它定了几个虚方法,分别如下:
public virtual TResponse BlockingUnaryCall<TRequest, TResponse>(); public virtual AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(); public virtual AsyncServerStreamingCall<TResponse> AsyncServerStreamingCall<TRequest, TResponse>(); public virtual AsyncClientStreamingCall<TRequest, TResponse> AsyncClientStreamingCall<TRequest, TResponse>(); public virtual AsyncDuplexStreamingCall<TRequest, TResponse> AsyncDuplexStreamingCall<TRequest, TResponse>(); public virtual Task<TResponse> UnaryServerHandler<TRequest, TResponse>(); public virtual Task<TResponse> ClientStreamingServerHandler<TRequest, TResponse>(); public virtual Task ServerStreamingServerHandler<TRequest, TResponse>(); public virtual Task DuplexStreamingServerHandler<TRequest, TResponse>();
各个方法作用如下:
| 方法名称 | 作用 | 
|---|---|
| BlockingUnaryCall | 拦截阻塞调用 | 
| AsyncUnaryCall | 拦截异步调用 | 
| AsyncServerStreamingCall | 拦截异步服务端流调用 | 
| AsyncClientStreamingCall | 拦截异步客户端流调用 | 
| AsyncDuplexStreamingCall | 拦截异步双向流调用 | 
| UnaryServerHandler | 用于拦截和传入普通调用服务器端处理程序 | 
| ClientStreamingServerHandler | 用于拦截客户端流调用的服务器端处理程序 | 
| ServerStreamingServerHandler | 用于拦截服务端流调用的服务器端处理程序 | 
| DuplexStreamingServerHandler | 用于拦截双向流调用的服务器端处理程序 | 
在实际使用中,可以根据自己的需要来使用对应的拦截方法。
三. 客户端拦截器
基于前面两篇文章使用的Demo。
在客户端项目新建一个类,命名为 ClientLoggerInterceptor,继承拦截器基类 Interceptor。
我们在前面使用的Demo,定义了撸猫服务,其中 SuckingCatAsync方法为异步调用,所以我们重写拦截器的 AsyncUnaryCall方法
public class ClientLoggerInterceptor:Interceptor
{
  public override AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(
    TRequest request,
    ClientInterceptorContext<TRequest, TResponse> context,
    AsyncUnaryCallContinuation<TRequest, TResponse> continuation)
  {
    LogCall(context.Method);
    return continuation(request, context);
  }
  private void LogCall<TRequest, TResponse>(Method<TRequest, TResponse> 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<ServerLoggerInterceptor> _logger;
  public ServerLoggerInterceptor(ILogger<ServerLoggerInterceptor> logger)
  {
    _logger = logger;
  }
  public override Task<TResponse> UnaryServerHandler<TRequest, TResponse>(
    TRequest request,
    ServerCallContext context,
    UnaryServerMethod<TRequest, TResponse> continuation)
  {
    LogCall<TRequest, TResponse>(MethodType.Unary, context);
    return continuation(request, context);
  }
  private void LogCall<TRequest, TResponse>(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<ServerLoggerInterceptor>();
  });
}
运行:
可以看到服务端成功拦截到了,客户端的调用。
五. 参考资料
.NET Core 上的 gRPC 的简介
本文Demo
到此这篇关于ASP.NET Core 3.0 gRPC拦截器的使用就介绍到这了。最深的陪伴是你明知道自己可怜却还对他爱不释手。更多相关ASP.NET Core 3.0 gRPC拦截器的使用内容请查看相关栏目,小编编辑不易,再次感谢大家的支持!