gRPC端到端处理元数据(标头)

时间:2019-12-16 13:56:26

标签: grpc grpc-java

我有由protobuf定义的服务(gRPC),该服务具有一种调用方法。 我想使用gRPC服务的clientStub调用该方法并传递标头(通常与其他方法一起使用),但是我找不到在gRPC中通常如何做。我决定通过 ClientInterceptor 进行操作,并将ClientInterceptor放入ClientStub。

public class ClientHeadersInterceptor implements ClientInterceptor {

    private static final Logger LOGGER = LoggerFactory.getLogger(ClientHeadersInterceptor.class);

    @Override
    public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(MethodDescriptor<ReqT, RespT> method, CallOptions callOptions, Channel next) {
        return new ForwardingClientCall.SimpleForwardingClientCall<ReqT, RespT>(next.newCall(method, callOptions)) {
            @Override
            public void start(Listener<RespT> responseListener, Metadata headers) {
                headers.put("test", "test");
                headers.put("test1", "test");
                super.start(new ForwardingClientCallListener.SimpleForwardingClientCallListener<RespT>(responseListener) {
                    @Override
                    public void onHeaders(Metadata headers) {
                        LOGGER.info("header received from server:" + headers);
                    }
                }, headers);
            }
        };
    }
}

所以我在业务逻辑中需要标头的这些值。我的意思是如何在gRPC的 impl 服务中获取这些值?

我通过创建 ServerInterceptor 来解决此问题,该服务器获取元数据的所有值并将其放在Context中。

@GRpcGlobalInterceptor
public class ServeInterceptor implements ServerInterceptor {

    @Override
    public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> serverCall,
                                                                 Metadata metadata,
                                                                 ServerCallHandler<ReqT, RespT> serverCallHandler) {
        Context current = Context.current();
        current = Context.current()
                    .withValue("test", metadata.get("test"))
                    .withValue("test1", metadata.get("test1"));


        return Contexts.interceptCall(current, serverCall, metadata, serverCallHandler);
    }


}

然后,最后,当我将所有内容都放在Context中时,我会在需要获取这些值的任何地方使用上下文。

String testValue = Context.key("test").get();
String test1Value = Context.key("test1").get();

那么,这真的是从客户端获取服务元数据(标头)的唯一方法吗?

0 个答案:

没有答案