ASP.NET Core gRPC 拦截器 - Go语言中文社区

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<TResponse> UnaryServerHandler<TRequest, TResponse>(TRequest request, ServerCallContext context, UnaryServerMethod<TRequest, TResponse> continuation)

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

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

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

客户端相关拦截方法:

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

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

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

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

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

服务端拦截器实现

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

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

客户端拦截器实现

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

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

public override AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(TRequest request, ClientInterceptorContext<TRequest, TResponse> context, AsyncUnaryCallContinuation<TRequest, TResponse> continuation)
{
  Console.WriteLine("客户端调用执行开始");
  var responseCon = continuation(request, context);
  var response = new AsyncUnaryCall<TResponse>(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<ServerInterceptor>();
});

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

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

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

result

参考链接

版权声明:本文来源简书,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://www.jianshu.com/p/12eef47f447c
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-02-02 14:53:18
  • 阅读 ( 1711 )
  • 分类:

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢