【问题标题】:gRCP intercept calls in C#gRCP 拦截 C# 中的调用
【发布时间】:2019-04-11 10:15:50
【问题描述】:

我在 C# (NETCore) 中使用 gRPC。我想记录每个单独的方法调用,并且我希望有某种方式可以一次拦截每个调用,而不是在每个服务方法上都记录一个日志。怎么没找到,但是不存在一些拦截策略?

【问题讨论】:

    标签: c# grpc


    【解决方案1】:

    可以为客户端和服务器端定义自定义拦截器。在这两种情况下,您都需要创建一个继承自 Interceptor 类的新类并覆盖您想要拦截的方法。对于客户端拦截器,它与整个客户端类相连。在服务器端拦截器仅为服务定义创建 - 这意味着如果您想要日志拦截器,您需要为每个服务定义指定它。此外,对于客户端,您可以使用已经可用的扩展方法和 Func 作为参数,该方法可用于简单的拦截场景(我不会向您展示它的代码,因为我现在无法访问它)。

    下面有简单的拦截器:

    public class GlobalServerLoggerInterceptor : Interceptor
    {
        private readonly ILogger logger;
    
        public GlobalServerLoggerInterceptor(ILogger logger)
        {
            this.logger = logger;
        }
    
        public override async Task<TResponse> UnaryServerHandler<TRequest, TResponse>(TRequest request, ServerCallContext context, UnaryServerMethod<TRequest, TResponse> continuation)
        {
            logger.Debug($"{Environment.NewLine}GRPC Request{Environment.NewLine}Method: {context.Method}{Environment.NewLine}Data: {JsonConvert.SerializeObject(request, Formatting.Indented)}");
    
            var response = await base.UnaryServerHandler(request, context, continuation);
    
            logger.Debug($"{Environment.NewLine}GRPC Response{Environment.NewLine}Method: {context.Method}{Environment.NewLine}Data: {JsonConvert.SerializeObject(response, Formatting.Indented)}");
    
            return response;
        }
    }
    

    为服务器端初始化拦截器(伪代码):

       var server = new Grpc.Core.Server
                {
                    Services =
                    {
    
    TestService.BindService(new TestImplementationService()).Intercept(IoC.Resolve<GlobalServerLoggerInterceptor>())
                    },
                    Ports = { new ServerPort("localhost", 1234, ServerCredentials.Insecure) }
                };
    

    在上面的例子中你可能会注意到这样的说法:

    .Intercept(IoC.Resolve<GlobalServerLoggerInterceptor>())
    

    如果您的拦截器需要引用其他一些类,您需要在运行服务器之前初始化它们。

    【讨论】:

    • 嗨,您找到了如何使拦截器工作的方法吗?我需要类似的东西。谢谢
    • @VAAA 在 2019 年 4 月没有文章和其他资源可以阅读,所以我对 gRPC C# 源代码进行了分析;)
    【解决方案2】:

    要使用 Grpc.Core 创建客户端拦截器,您可以执行以下操作:

    var clientInterceptor = new YourClientInterceptor();
    var channel = new Channel($"localhost", ChannelCredentials.Insecure);
    var interceptingInvoker = channel.Intercept(clientInterceptor);
    var client = new YourServiceClient(interceptingInvoker);
    

    注意channel.Intercept(clientInterceptor) 如何返回一个新的调用调用程序供您传递给客户端。那里的命名有点不直观,但这就是我们现在所拥有的。

    要拦截客户端调用,让您的拦截器覆盖/实现您需要的所有...Call 方法,例如BlockingUnaryCall(...)AsyncUnaryCall(...)

    【讨论】:

      猜你喜欢
      • 2010-12-09
      • 1970-01-01
      • 1970-01-01
      • 2013-10-04
      • 2015-04-29
      • 1970-01-01
      • 2011-07-13
      • 1970-01-01
      相关资源
      最近更新 更多