gRPC之拦截器与元数据

简介

  1. 用户可以通过访问或者修改Metadata来传递额外的信息(即HTTP/2的Header信息),比如认证信息、TraceId、RequestId等
    • Metadata是以key-value的形式存储数据的。其中key是字符串类型,value是字符串数组类型
    • Metadata 的生命周期则是一次 RPC 调用
  2. gRPC可以在四个地方增加拦截处理
    • 客户端调用前的拦截
    • 客户端收到的回复拦截
    • 服务端收到的请求拦截
    • 服务端回复前的拦截

客户端拦截器案例

  1. 客户端调用前拦截器

    @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();
                }
            };
        }
    }
    
  2. 客户端调用后拦截器

    @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);
                }
            };
        }
    }
    
  3. 客户端传递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(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值