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