ASP.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
,这里通过实现 同步/异步 客户端简单调用的拦截方法 BlockingUnaryCall
、 AsyncUnaryCall
进行说明,最终需按实际开发情况实现更多拦截方法。
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(); });
客户端配置拦截通过 channel
的 Intercept
方法,如下:
var channel = GrpcChannel.ForAddress("https://localhost:5001"); var invoker = channel.Intercept(new ClientInterceptor()); var client = new Greeter.GreeterClient(invoker);
服务端和服务端拦截器的配置都可支持多个,如果同时指定多个拦截器会按照添加顺序依次执行