当 ServerCall 在第一个 ServerInterceptro 中关闭时如何忽略 gRPC(java) ServerInterceptor 的其余部分?

How to ignore rest of gRPC(java) ServerInterceptor when ServerCall closed in first ServerInterceptro?

我在 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);
           }
      }
}

由于拦截器是链接的,您可以从监听器中获取关闭事件。与其直接返回从 next 获得的 ServerCall.Listener,不如创建一个新的委托:

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

您可以使用 SimpleForwardingServerCall 朝另一个方向对 ServerCall 做类似的事情。

拦截器不需要调用 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() {};
         }
     }
}