简介
- 用户可以通过访问或者修改
Metadata
来传递额外的信息(即HTTP/2的Header信息),比如认证信息、TraceId、RequestId等Metadata
是以key-value的形式存储数据的。其中key是字符串类型,value是字符串数组类型Metadata
的生命周期则是一次 RPC 调用
- gRPC可以在四个地方增加拦截处理
- 客户端调用前的拦截
- 客户端收到的回复拦截
- 服务端收到的请求拦截
- 服务端回复前的拦截
客户端拦截器案例
-
客户端调用前拦截器
@Slf4j public class ClientPreInterceptor implements ClientInterceptor { @Override public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(MethodDescriptor<ReqT, RespT> method, CallOptions callOptions, Channel next) { final String methodName = method.getFullMethodName(); return new ForwardingClientCall.SimpleForwardingClientCall<ReqT, RespT>(next.newCall(method, callOptions)) { @Override public void start(Listener<RespT> responseListener, Metadata headers) { log.info("调用{}开始", methodName); super.start(responseListener, headers); } @Override public void sendMessage(ReqT message) { log.info("方法:{}发送消息:{}", methodName, message); super.sendMessage(message); } @Override public void request(int numMessages) { log.info("方法:{} 传递给侦听器的请求的消息数:{}", methodName, numMessages); super.request(numMessages); } @Override public void halfClose() { log.info("方法:{}客户端半关闭", methodName); super.halfClose(); } }; } }
-
客户端调用后拦截器
@Slf4j public class ClientPostInterceptor implements ClientInterceptor { @Override public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(MethodDescriptor<ReqT, RespT> method, CallOptions callOptions, Channel next) { final String methodName = method.getFullMethodName(); return new ForwardingClientCall.SimpleForwardingClientCall<ReqT, RespT>(next.newCall(method, callOptions)) { @Override public void start(Listener<RespT> responseListener, Metadata headers) { ForwardingClientCallListener.SimpleForwardingClientCallListener<RespT> simpleForwardingClientCallListener = new ForwardingClientCallListener.SimpleForwardingClientCallListener<RespT>(responseListener) { @Override public void onMessage(RespT message) { log.info("客户端已经接收到响应消息,methodName:{},message:{}", methodName, message); super.onMessage(message); } @Override public void onHeaders(Metadata headers) { log.info("已经收到响应头,methodName:{}", methodName); super.onHeaders(headers); } @Override public void onClose(Status status, Metadata trailers) { log.info("客户端关闭连接,methodName:{},code:{}", methodName, status.getCode()); super.onClose(status, trailers); } @Override public void onReady() { log.info("客户端onReady,methodName:{}", methodName); super.onReady(); } }; super.start(simpleForwardingClientCallListener, headers); } }; } }
-
客户端传递Metadata
//放到api包(服务端和客户端都依赖api包) public class Constant { public static final Context.Key<String> TRACE_ID_CTX_KEY = Context.key("traceId"); public static final Metadata.Key<String> TRACE_ID_METADATA_KEY = Metadata.Key.of(