Grpc远程调用-客户端服务端传参问题-已解决

采用Grpc调用远程服务(博主的服务是注册在eureka上的),一般是通过grpc的stub对象去调用,如果需要向服务端传递参数,比如日志追踪用到的traceId,这个时候可以使用grpc的拦截器去实现。实现步骤如下

1.客户端

1.1 客户端先新建拦截器,实现ClientInterceptor接口,代码如下

package cn.swiftpass.upay.payment.ags.interceptor.grpc;


import io.grpc.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.MDC;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.UUID;

/**
 * grpc客户端拦截器
 * @author *********
 * @date 2022/1/13 14:34
 * @Description
 */
@GrpcGlobalClientInterceptor
@Slf4j
@Component
public class GrpcClientInterceptor implements ClientInterceptor {

    //客户端header的ORDER_TRACE
    static final Metadata.Key<String> ORDER_TRACE = Metadata.Key.of(SysParamConstant.ORDER_TRACE, Metadata.ASCII_STRING_MARSHALLER);

    @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) {
                // 将订单追踪对象放入header中,供下一步应用使用
                addOrderTrace(headers);
                // 继续下一步
                super.start(new ForwardingClientCallListener.SimpleForwardingClientCallListener<RespT>(responseListener) {
                    @Override
                    public void onHeaders(Metadata headers) {
                        //服务端传递回来的header
                        log.info("header received from server {}", headers);
                        super.onHeaders(headers);
                    }
                }, headers);
            }
        };
    }

    /**
     *  将订单追踪对象放入header中
     * @param headers
     */
    private void addOrderTrace(Metadata headers) {
        RequestHolder holder = RequestHolder.getFromRequestContext();
        //放入客户端的header
        headers.put(ORDER_TRACE, JsonUtil.obj2String(holder.getOrderTrace()));
    }
}

        1.2 改造服务调用时的stub,具体如下,stub是通过自动注入获取的

Channel channel = ClientInterceptors.intercept(stub.getChannel(), new GrpcClientInterceptor());
        stub= *****grpc.newFutureStub(channel);

2.改造服务端,实现ServerInterceptor接口,代码如下

package cn.swiftpass.upay.payment.config;


import io.grpc.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.MDC;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.UUID;

/**
 * @author *****
 * @date 2022/1/13 15:22
 * @Description
 */
@GrpcGlobalServerInterceptor
@Slf4j
@Component
public class GrpcServerInterceptor implements ServerInterceptor {

    //客户端header的traceId
    static final Metadata.Key<String> ORDER_TRACE = Metadata.Key.of(SysParamConstant.ORDER_TRACE, Metadata.ASCII_STRING_MARSHALLER);

    @Override
    public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(
            ServerCall<ReqT, RespT> call,
            final Metadata requestHeaders,
            ServerCallHandler<ReqT, RespT> next) {
        // @1 从客户端设置的header信息-traceid
        log.info("grpc header received from client:" + requestHeaders);
        OrderTrace orderTrace = JsonUtil.string2Obj(requestHeaders.get(ORDER_TRACE),OrderTrace.class);
        log.info("订单追踪orderTrace = {}",orderTrace);
        // 继续
        return next.startCall(new ForwardingServerCall.SimpleForwardingServerCall<ReqT, RespT>(call) {

            @Override
            public void sendHeaders(Metadata responseHeaders) {
                // @2 响应客户端设置服务端Header信息
                super.sendHeaders(responseHeaders);
            }

            @Override
            public void close(Status status, Metadata trailers) {
                super.close(status, trailers);
            }
        }, requestHeaders);
    }
}

3.结果

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值