GRPC 上下文传递数据

项目还是基于springcloud+nacos+grpc

场景:登录后,需要把userId进行上下文共享,也就是在整个微服务构架内,都可以使用,或都说通过header把基本数据进行传递。

1. 客户端传递数据

使用fegin进行服务间调用,可以使用如下方法

1.直接在请求方法上,加上@Headers(value={"ContentType=application/x-www-form-urlencoded","k=v"})
2.在需要调用的类上,增加拦截器,继承RequestInterceptor

3.直接在请求参数内,加上@RequestHeader

GRPC需要使用MetadataUtils包中attachHeaders方法来实现

步骤1.

创建MetadataUtilsExt类,来重新封装attachHeaders,不封装直接用也行

public class MetadataUtilsExt {

    public static <T extends AbstractStub<T>> T attachContext(T stub, final Map<String, String> contextMap) {
        Metadata context = new Metadata();
        if (contextMap != null) {
            for (String key : contextMap.keySet()) {
                Metadata.Key<String> customHeadKey = Metadata.Key.of(key, Metadata.ASCII_STRING_MARSHALLER);
                context.put(customHeadKey, contextMap.get(key));
            }
        }
        return MetadataUtils.attachHeaders(stub, context);
    }
}

步骤2.

在请求客户端的方法上,调用该方法(创建一个map,然后把map传过去) 

2. 服务端接收数据 

fegin调用这种方式,是经过controller,可以在controller直接获取header信息。而GRPC直接在service上,这里就需要使用拦截器(ServerInterceptor)进行拦截。GRPC的拦截器,属于全双工通信,在server的拦截器中也可以返回数据,client端接收时,需要使用clientInterceptor。

@Slf4j
@Component
@GrpcGlobalServerInterceptor
public class Interceptor implements ServerInterceptor {

    @Override
    public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> serverCall, Metadata metadata, ServerCallHandler<ReqT, RespT> serverCallHandler) {

        //获取客户端参数
        Metadata.Key<String> userId = Metadata.Key.of("userId", Metadata.ASCII_STRING_MARSHALLER);
        String userIdStr = metadata.get(userId);
        log.info("userId : {}",userIdStr);

        //服务端写回参数
        ServerCall<ReqT, RespT> call = new ForwardingServerCall.SimpleForwardingServerCall<ReqT, RespT>(serverCall) {
            @Override
            public void sendHeaders(Metadata headers) {
                super.sendHeaders(headers);
            }
        };
        return serverCallHandler.startCall(call,metadata);
    }
}

测试

 

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
gRPC是一种高性能、开源的跨语言远程过程调用(RPC)框架,它基于Protocol Buffers(protobuf)进行数据序列化和传输。在gRPC中,可以通过gRPC提供的生成的客户端和服务器端代码来使用远程函数调用。下面是gRPC Go传递函数的实现原理: 1. 通过gRPC生成器生成相应的gRPC服务端和客户端代码。 2. 在服务端,我们可以定义一个服务接口,该接口包含我们希望远程调用的函数。同时,我们还可以为接口定义一个结构体,它可以作为我们的服务实例,包含函数调用的具体实现。 3. 在客户端,我们可以使用生成的客户端代码,创建一个gRPC连接,并调用远程函数。客户端代码会将函数的参数序列化为protobuf格式的数据,并通过gRPC连接发送给服务器。 4. 服务器接收到远程函数调用请求后,会将接收到的数据反序列化,并将其传递给实现该函数调用的服务实例。服务实例会执行相应的函数逻辑,并根据需要返回结果。 5. 服务器再次将结果序列化为protobuf格式的数据,并通过gRPC连接发送给客户端。 6. 客户端接收到结果后,会将其反序列化,并将结果返回给调用该远程函数的代码。 通过上述步骤,gRPC Go实现了客户端和服务器端之间的远程函数调用。它利用protobuf作为数据的序列化和传输格式,通过gRPC连接来建立通信,并通过生成的代码处理函数的参数传递和结果返回。由于gRPC采用了HTTP/2协议,它能够提供高性能的跨语言远程函数调用。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值