【问题标题】:How to ignore rest of gRPC(java) ServerInterceptor when ServerCall closed in first ServerInterceptro?当 ServerCall 在第一个 ServerInterceptro 中关闭时,如何忽略 gRPC(java) ServerInterceptor 的其余部分?
【发布时间】:2017-06-27 06:00:24
【问题描述】:

我在一个 gRPC 服务上绑定了 2 个 ServerInterceptor。

在第一个拦截器中,ServerCall 已经关闭,但第二个拦截器仍然参与其中。

那么如何在第一个拦截器中关闭 ServerCall 时跳过其余的拦截器?

第一个拦截器:

public class FirstInterceptor implements ServerInterceptor {

      @Override
      public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(
           ServerCall<ReqT, RespT> call,
           Metadata headers,
           ServerCallHandler<ReqT, RespT> next) {

           if(...){
               ...
               return Contexts.interceptCall(context, call, headers, next);
           }else{
               ...
               call.close(Status.UNAUTHENTICATED.withDescription("@FST_INTCP"),GrpcUtil.getMetadataWithErrMsg(e));
               return next.startCall(new ForwardingServerCall.SimpleForwardingServerCall<ReqT, RespT>(call) {}, headers);
           }
      }
}

【问题讨论】:

    标签: java server interceptor grpc


    【解决方案1】:

    拦截器不需要调用next。如果您在interceptCall() 期间关闭ServerCall,则无需调用next,因为链中的其他任何东西都无法响应。

    所以代码看起来像:

    public class FirstInterceptor implements ServerInterceptor {
        @Override
        public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(
                 ServerCall<ReqT, RespT> call,
                 Metadata headers,
                 ServerCallHandler<ReqT, RespT> next) {
             if(...) {
                 ...
                 return Contexts.interceptCall(context, call, headers, next);
             } else {
                 ...
                 call.close(Status.UNAUTHENTICATED.withDescription("@FST_INTCP"),
                     GrpcUtil.getMetadataWithErrMsg(e));
                 return new ServerCall.Listener() {};
             }
         }
    }
    

    【讨论】:

      【解决方案2】:

      由于拦截器是链式的,你可以从监听器中获取关闭事件。您可以创建一个新的代表:

      ServerCall.Listener<ReqT> delegate = Contexts.interceptCall(context, call, headers, next);
      return new SimpleForwardingServerCallListener<ReqT>(delegate) {
        boolean cancelled;
        @Override
        void onCancel() {
          cancelled = true;
        }
      
        @Override 
        void onMessage(Req req) {
          if (cancelled) {
            return;
          }
          // normal logic here.
        }
      }
      

      SimpleForwardingServerCallListener

      您可以使用SimpleForwardingServerCallServerCall 执行类似的操作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-10-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-01-31
        • 1970-01-01
        相关资源
        最近更新 更多