Use of asp.net core 3.0 grpc interceptor

Time:2020-3-24

I. Preface

The first two articles introduce you to the introduction of grpc and the use of two-way flow. Today, we introduce the interceptor in grpc. Like MVC filter or asp.net core middleware, interceptor has the idea of face-to-face. It can carry out some unified processing when invoking services, which is very suitable for processing validation, log and other processes here. This article takes logging as an example to explain.

2、 Introduction to interceptor class

InterceptorClass is the base class and abstract class of grpc service interceptor. It defines several virtual methods as follows:


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>();

The functions of each method are as follows:

Method name Effect
BlockingUnaryCall Block block call
AsyncUnaryCall Block asynchronous calls
AsyncServerStreamingCall Block asynchronous service end stream calls
AsyncClientStreamingCall Block asynchronous client stream calls
AsyncDuplexStreamingCall Block asynchronous two-way flow calls
UnaryServerHandler Used to intercept and pass in normal call server-side handlers
ClientStreamingServerHandler Server side handler for intercepting client stream calls
ServerStreamingServerHandler Server side handler for intercepting service side stream calls
DuplexStreamingServerHandler Server side handler for intercepting two-way flow calls

In practice, you can use the corresponding interception method according to your own needs.

3、 Client blocker

Based on the demo used in the previous two articles.

Create a new class in the client project namedClientLoggerInterceptor, inherit interceptor base classInterceptor

The demo we used earlier defines the “rolling cat” service, whereSuckingCatAsyncMethod is called asynchronously, so we override the interceptor’sAsyncUnaryCallMethod


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;
  }
}

Register Interceptor:

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 ("call the call service:" + catreply. Message);

Then run:

You can see that the call is successfully intercepted at the client side and the call information is recorded.

4、 Server interceptor

Create a new class in the server project namedServerLoggerInterceptor, inherit interceptor base classInterceptor

The method we need to implement on the server isUnaryServerHandler


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)}");
  }
}

Register Interceptor:


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

Function:

You can see that the server successfully intercepts the call from the client.

5、 References

Introduction to grpc on. Net core

This article Demo

The above is the whole content of this article. I hope it will help you in your study, and I hope you can support developepaer more.