RPC项目Interceptor拦截器的使用

// 注入
services.AddGrpc(opt =>
{
    opt.EnableDetailedErrors = true;
    opt.Interceptors.Add<LogInterceptor>();
});
 
/// <summary>
/// 服务端拦截器
/// </summary>
public class LogInterceptor : Interceptor
{
    private readonly ILogger<LogInterceptor> _logger;
    private AppConfig _appConfig;

    public LogInterceptor(ILogger<LogInterceptor> logger, IOptionsSnapshot<AppConfig> appConfig)
    {
        _logger = logger;
        _appConfig = appConfig.Value;
    }

    public override async Task<TResponse> UnaryServerHandler<TRequest, TResponse>(
        TRequest request,
        ServerCallContext context,
        UnaryServerMethod<TRequest, TResponse> continuation)
    {
        try
        {
            var response = await continuation(request, context);

            if (_appConfig.ShowRequestLog)
            {
                _logger.LogInformation($"Started call Method: { context.Method}. Request: {request}. Response: {response}. Status: { context.Status}");
            }

            return response;
        }
        catch (System.Exception ex)
        {
            _logger.LogError(ex, $"异常 Call Method: { context.Method}. Request: {request}");
        }

        return null;

    }
}

###第一种注入方式
services.AddGrpcClient<Client>(o =>
{
    o.Address = new System.Uri("http://localhost:5002");
}).EnableCallContextPropagation(o => o.SuppressContextNotFoundErrors = true)
.AddInterceptor<ErrorInterceptor>();

###第二种注入方式
readonly CallInvoker _grpcChannel;
public ClassNameGrpc(IOptionsMonitor<ApiConfig> apiConfig, ErrorInterceptor errorInterceptor)
{
     _grpcChannel = GetGrpcChannel(errorInterceptor, apiConfig.CurrentValue.Api.Address);
}
public CallInvoker GetGrpcChannel(ErrorInterceptor errorInterceptor, string url)
{
     var defaultMethodConfig = new MethodConfig
     {
         Names = { MethodName.Default },
         RetryPolicy = new RetryPolicy
         {
             MaxAttempts = 2,
             InitialBackoff = TimeSpan.FromSeconds(1),
             MaxBackoff = TimeSpan.FromSeconds(5),
             BackoffMultiplier = 1.5,
             RetryableStatusCodes = { StatusCode.Unavailable }
         }
     };
     var grpcChannel = GrpcChannel.ForAddress(url, new GrpcChannelOptions
     {
         ServiceConfig = new ServiceConfig { MethodConfigs = { defaultMethodConfig } },
         HttpClient = new System.Net.Http.HttpClient()
         {
             Timeout = TimeSpan.FromSeconds(10)
         }
     });
     return grpcChannel.Intercept(errorInterceptor);
 }

###客户端拦截器
using Grpc.Core;
using Grpc.Core.Interceptors;
using Microsoft.Extensions.Logging;
using System.Threading.Tasks;

namespace MallWin.Live.GrpcClient.Core
{
    /// <summary>
    /// 拦截器
    /// </summary>
    public class ErrorInterceptor : Interceptor
    {
        private readonly ILogger<ErrorInterceptor> _logger;

        public ErrorInterceptor(ILogger<ErrorInterceptor> logger)
        {
            _logger = logger;
        }

        public override AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(
            TRequest request,
            ClientInterceptorContext<TRequest, TResponse> context,
            AsyncUnaryCallContinuation<TRequest, TResponse> continuation)
        {
            var call = continuation(request, context);

            return new AsyncUnaryCall<TResponse>(HandleResponse(context.Method, request, call.ResponseAsync), call.ResponseHeadersAsync, call.GetStatus, call.GetTrailers, call.Dispose);
        }

        private async Task<TResponse> HandleResponse<TRequest, TResponse>(Method<TRequest, TResponse> method, TRequest request, Task<TResponse> responseTask)
        {
            try
            {
                var response = await responseTask;
                return response;
            }
            catch (RpcException ex)
            {
                _logger.LogError(ex, $"LiveApi调用GRPC异常 Call Method:{method.FullName} Request: {request}");
                return System.Activator.CreateInstance<TResponse>();
            }
        }
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值