GRPC 上下文传递数据
项目还是基于springcloud+nacos+grpc场景:登录后,需要把userId进行上下文共享,也就是在整个微服务构架内,都可以使用,或都说通过header把基本数据进行传递。1. 客户端传递数据使用fegin进行服务间调用,可以使用如下方法1.直接在请求方法上,加上@Headers(value={"ContentType=application/x-www-form-urlencoded
项目还是基于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);
}
}
测试
更多推荐
所有评论(0)