gRPC请求中对header进行处理

gRPC请求设置header(Android、iOS、JavaServer) 1.[Android (Java)]
1.1只设置客户端请求时附带的header 见类 io.grpc.stub.MetadataUtils,其中有个方法:

/** * Attaches a set of request headers to a stub. * * @param stub to bind the headers to. * @param extraHeaders the headers to be passed by each call on the returned stub. * @return an implementation of the stub with {@code extraHeaders} bound to each call. */ @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1789") public static > T attachHeaders( T stub, final Metadata extraHeaders) { return stub.withInterceptors(newAttachHeadersInterceptor(extraHeaders)); }

稍微自己封装一下的效果,如下:
private static > T attachHeaders(T stub, final Map headerMap) { Metadata extraHeaders = new Metadata(); if (headerMap != null) { for (String key : headerMap.keySet()) { Metadata.Key customHeadKey = Metadata.Key.of(key, Metadata.ASCII_STRING_MARSHALLER); extraHeaders.put(customHeadKey, headerMap.get(key)); } } return MetadataUtils.attachHeaders(stub, extraHeaders); }

1.2 支持设置客户端请求的header以及获取服务端返回结果中的header 第一步:主要是设置http的拦截器ClientInterceptor,拦截器类大概实现代码如下:
/** * A interceptor to handle client header. * * @author Kido * @email everlastxgb@gmail.com * @create_time 2016/7/7 11:02 */class HeaderClientInterceptor implements ClientInterceptor {private static final String TAG = "HeaderClientInterceptor"; private Map mHeaderMap; public HeaderClientInterceptor(Map headerMap) { mHeaderMap = headerMap; }@Override public ClientCall interceptCall(MethodDescriptor method, CallOptions callOptions, Channel next) { return new SimpleForwardingClientCall(next.newCall(method, callOptions)) {@Override public void start(Listener responseListener, Metadata headers) { /* put custom header */ if (mHeaderMap != null) { for (String key : mHeaderMap.keySet()) { Metadata.Key customHeadKey = Metadata.Key.of(key, Metadata.ASCII_STRING_MARSHALLER); headers.put(customHeadKey, mHeaderMap.get(key)); } } Logger.i(TAG, "header send to server:" + headers); super.start(new SimpleForwardingClientCallListener(responseListener) { @Override public void onHeaders(Metadata headers) { /** * if you don't need receive header from server, * you can use {@link io.grpc.stub.MetadataUtils attachHeaders} * directly to send header */ Logger.i(TAG, "header received from server:" + headers); super.onHeaders(headers); } }, headers); } }; } }

第二步:大概使用代码如下:
Map headerMap = new HashMap<>(); //... ClientInterceptor interceptor = new HeaderClientInterceptor(headerMap); //... ManagedChannel managedChannel = ManagedChannelBuilder.forAddress(host, port).usePlaintext(true).build(); Channel channel = ClientInterceptors.intercept(managedChannel, interceptor); // then create stub here by this channel

2. [iOS (Objective-C)]
首先,可以看到GRPCCall中有如下属性:
@property(atomic, readonly) NSDictionary *responseHeaders; @property(atomic, readonly) NSDictionary *responseTrailers;

接着,可以进行如下设置:
call.requestHeaders[@"My-Header"] = @"Value for this header"; call.requestHeaders[@"Another-Header"] = @"Its value";

3.[Server (Java)]
既然是Java,实现方式应该也和上述Android大概一样。
第一步:拦截器
/** * A interceptor to handle server header. */ public class HeaderServerInterceptor implements ServerInterceptor {private static final Logger logger = Logger.getLogger(HeaderServerInterceptor.class.getName()); private static Metadata.Key customHeadKey = Metadata.Key.of("custom_server_header_key", Metadata.ASCII_STRING_MARSHALLER); @Override public ServerCall.Listener interceptCall( ServerCall call, final Metadata requestHeaders, ServerCallHandler next) { logger.info("header received from client:" + requestHeaders); return next.startCall(new SimpleForwardingServerCall(call) { @Override public void sendHeaders(Metadata responseHeaders) { responseHeaders.put(customHeadKey, "customRespondValue"); super.sendHeaders(responseHeaders); } }, requestHeaders); } }

【gRPC请求中对header进行处理】第二步:使用示例
//... Server server = ServerBuilder.forPort(port) .addService(ServerInterceptors.intercept(new GreeterImpl(), new HeaderServerInterceptor())) .build() .start(); //...

    推荐阅读