ASP.NET Core 3.0 gRPC 攔截器

目錄

一. 前言

前面兩篇文章給你們介紹了使用gRPC的入門以及雙向流的使用,今天介紹的是gRPC中的攔截器。攔截器就像MVC的過濾器或者是ASP.NET Core middleware 同樣,具備面向切面的思想,能夠在調用服務的時候進行一些統一處理, 很適合在這裏處理驗證、日誌等流程。本片文章就以記錄日誌爲例來進行講解。html

二. Interceptor 類介紹

Interceptor類是gRPC服務攔截器的基類,是一個抽象類,它定了幾個虛方法,分別以下:git

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

各個方法做用以下:github

方法名稱 做用
BlockingUnaryCall 攔截阻塞調用
AsyncUnaryCall 攔截異步調用
AsyncServerStreamingCall 攔截異步服務端流調用
AsyncClientStreamingCall 攔截異步客戶端流調用
AsyncDuplexStreamingCall 攔截異步雙向流調用
UnaryServerHandler 用於攔截和傳入普通調用服務器端處理程序
ClientStreamingServerHandler 用於攔截客戶端流調用的服務器端處理程序
ServerStreamingServerHandler 用於攔截服務端流調用的服務器端處理程序
DuplexStreamingServerHandler 用於攔截雙向流調用的服務器端處理程序

在實際使用中,能夠根據本身的須要來使用對應的攔截方法。服務器

三. 客戶端攔截器

基於前面兩篇文章使用的Demo。異步

在客戶端項目新建一個類,命名爲 ClientLoggerInterceptor,繼承攔截器基類 Interceptoride

咱們在前面使用的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;
    }
}

註冊攔截器:code

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

而後運行:htm

image-20191112105159256

能夠看到成功的在客戶端攔截到了調用,並記錄了調用信息。blog

四. 服務端攔截器

在服務端項目新建一個類,命名爲 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>();
    });
}

運行:

image-20191112110227838

能夠看到服務端成功攔截到了,客戶端的調用。

五. 參考資料

.NET Core 上的 gRPC 的簡介

本文Demo

相關文章
相關標籤/搜索