.NET Core gRPC 拦截器

gRPC 作为一套独立的 RPC 框架,像拦截器这种功能当然也是不可或缺的,框架自带的拦截器更多是基于框架本身出发,对于 gRPC 来说最突出的就是需要支持各种不同 RPC 调用方式的拦截,如:简单 RPC 调用流式 RPC 调用,流式调用又分 客户端流式调用服务端流式调用双向流式调用,关于流式调用更多介绍可参考:ASP.NET Core gRPC 流式调用。

拦截器分类

不论是基于 .NET Core 2.x 或 3.x,都需要依赖 Grpc.Core 这个 NuGet Package,Grpc.Core 中已提供拦截器(Interceptor 类)功能(不过如果使用的版本过低,可能不支持拦截器,我们之前经历过这个阶段)。拦截器中的方法分两类,分别作用于客户端(客户端向服务端发请求时拦截) 和 服务端(服务端接收到客户端请求时拦截)。

服务端相关拦截方法:

// 简单调用拦截
public virtual Task UnaryServerHandler(TRequest request, ServerCallContext context, UnaryServerMethod continuation)

// 客户端流式调用拦截
public virtual Task ClientStreamingServerHandler(IAsyncStreamReader requestStream, ServerCallContext context, ClientStreamingServerMethod continuation)

// 服务端流式调用拦截
public virtual Task ServerStreamingServerHandler(TRequest request, IServerStreamWriter responseStream, ServerCallContext context, ServerStreamingServerMethod continuation)

// 双向流调用拦截
public virtual Task DuplexStreamingServerHandler(IAsyncStreamReader requestStream, IServerStreamWriter responseStream, ServerCallContext context, DuplexStreamingServerMethod continuation)

客户端相关拦截方法:

// 同步简单调用拦截
public virtual TResponse BlockingUnaryCall(TRequest request, ClientInterceptorContext context, BlockingUnaryCallContinuation continuation)

// 异步简单调用拦截
public virtual AsyncUnaryCall AsyncUnaryCall(TRequest request, ClientInterceptorContext context, AsyncUnaryCallContinuation continuation)

// 异步服务端流式调用拦截
public virtual AsyncServerStreamingCall AsyncServerStreamingCall(TRequest request, ClientInterceptorContext context, AsyncServerStreamingCallContinuation continuation)

// 异步客户端流式调用拦截
public virtual AsyncClientStreamingCall AsyncClientStreamingCall(ClientInterceptorContext context, AsyncClientStreamingCallContinuation continuation)

// 异步双向流调用拦截
public virtual AsyncDuplexStreamingCall AsyncDuplexStreamingCall(ClientInterceptorContext context, AsyncDuplexStreamingCallContinuation continuation)

服务端拦截器实现

创建 ServerInterceptor 继承于抽象类 Interceptor,这里通过实现简单调用的服务端拦截方法 UnaryServerHandler 进行说明,最终需按实际开发情况实现更多拦截方法。

public override async Task UnaryServerHandler(TRequest request, ServerCallContext context, UnaryServerMethod continuation)
{
  Console.WriteLine("服务端执行开始");
  var response = await continuation(request, context);
  Console.WriteLine("服务端执行结束");
  return response;
}

客户端拦截器实现

创建 ClientInterceptor 继承于抽象类 Interceptor,这里通过实现 同步/异步 客户端简单调用的拦截方法 BlockingUnaryCallAsyncUnaryCall 进行说明,最终需按实际开发情况实现更多拦截方法。

public override TResponse BlockingUnaryCall(TRequest request, ClientInterceptorContext context, BlockingUnaryCallContinuation continuation)
{
  Console.WriteLine("客户端调用执行开始");
  var response = continuation(request, context);
  Console.WriteLine("客户端调用执行结束");
  return response;
}

public override AsyncUnaryCall AsyncUnaryCall(TRequest request, ClientInterceptorContext context, AsyncUnaryCallContinuation continuation)
{
  Console.WriteLine("客户端调用执行开始");
  var responseCon = continuation(request, context);
  var response = new AsyncUnaryCall(responseCon.ResponseAsync, responseCon.ResponseHeadersAsync, responseCon.GetStatus, responseCon.GetTrailers, responseCon.Dispose);
  Console.WriteLine("客户端调用执行结束");
  return response;
}

拦截器配置

.NET Core 3.0 后配置方式如下:

服务端配置拦截器可通过在 ConfigureServices 中通过 services.AddGrpc 中的 GrpcServiceOptions 来指定 Interceptors,如下:

services.AddGrpc(options =>
{
  options.Interceptors.Add();
});

客户端配置拦截通过 channelIntercept 方法,如下:

var channel = GrpcChannel.ForAddress("https://localhost:5001");
var invoker = channel.Intercept(new ClientInterceptor());
var client = new Greeter.GreeterClient(invoker);

服务端和服务端拦截器的配置都可支持多个,如果同时指定多个拦截器会按照添加顺序依次执行

result

参考链接

  • gRPC Interceptor Sample

你可能感兴趣的:(.NET Core gRPC 拦截器)