grpc拦截器

在grpc的报文中可以增加报文头,用于标注消息的元数据。
服务端拦截器 在服务端可以继承ServerInterceptor来实现服务端的拦截器,用于操作报文头:

public class MyServerInterceptor implements ServerInterceptor { //服务端header的key static final Metadata.Key CUSTOM_HEADER_KEY = Metadata.Key.of("serverHeader", Metadata.ASCII_STRING_MARSHALLER); @Override public ServerCall.Listener interceptCall(ServerCall call, Metadata headers, ServerCallHandler next) { //输出客户端传递过来的header System.out.println("header received from client:" + headers); return next.startCall(new ForwardingServerCall.SimpleForwardingServerCall(call) { @Override public void sendHeaders(Metadata responseHeaders) { //在返回中增加header responseHeaders.put(CUSTOM_HEADER_KEY, "response"); super.sendHeaders(responseHeaders); } }, headers); } }

客户端拦截器 类似的,需要继承ClientInterceptor实现客户端的拦截器
public class MyClientInterceptor implements ClientInterceptor { //客户端header的key static final Metadata.Key CUSTOM_HEADER_KEY = Metadata.Key.of("clientHeader", Metadata.ASCII_STRING_MARSHALLER); @Override public ClientCall interceptCall(MethodDescriptor method, CallOptions callOptions, Channel next) { return new ForwardingClientCall.SimpleForwardingClientCall(next.newCall(method, callOptions)) { @Override public void start(Listener responseListener, Metadata headers) { //放入客户端的header headers.put(CUSTOM_HEADER_KEY, "request"); super.start(new ForwardingClientCallListener.SimpleForwardingClientCallListener(responseListener) { @Override public void onHeaders(Metadata headers) { //输出服务端传递回来的header System.out.println("header received from server:" + headers); super.onHeaders(headers); } }, headers); } }; } }

调用 在完成两端的拦截器的代码就需要使用它们了,它们的用法是在客户端channel或服务端的构建过程中将它们注入到对应的客户端/服务端header的key,下面我们在上次代码的基础上进行修改
//服务端 public class IntceptorServer {private int port; private Server server; public IntceptorServer(int port) throws IOException { this.port=port; server= ServerBuilder.forPort(port) //将MyServerInterceptor注册到服务端 .addService(ServerInterceptors.intercept(new HelloServiceImpl(),new MyServerInterceptor())) .build(); server.start(); System.out.println("Server started, listening on " + port ); }private void blockUntilShutdown() throws InterruptedException { while(true){ server.awaitTermination(); } } public static void main(String[] args) throws Exception { (new IntceptorServer(8080)).blockUntilShutdown(); } }//客户端 public class InterceporClient { static final Metadata.Key ATTCHED_HEADER = Metadata.Key.of("attached_header", Metadata.ASCII_STRING_MARSHALLER); public static voidmain(String[] args) throws InterruptedException { final ManagedChannel originalChannel = ManagedChannelBuilder.forAddress("127.0.0.1", 8080).usePlaintext(true).build(); //将MyClientInterceptor和原有的channel结合,生成包含拦截器的channel Channel channel = ClientInterceptors.intercept(originalChannel, new MyClientInterceptor()); HelloServiceGrpc.HelloServiceBlockingStub blockingStub = HelloServiceGrpc.newBlockingStub(channel); ProtoObj.Person person = ProtoObj.Person.newBuilder().setMyName("World").build(); System.out.println(blockingStub.simpleHello(person).getString()); //如果只需要在客户端传送header,而不需要接受服务端的header可以简单调用MetadataUtils.attachHeaders注册meta数据而不用定义Interceptor blockingStub = HelloServiceGrpc.newBlockingStub(originalChannel); Metadata meta=new Metadata(); meta.put(ATTCHED_HEADER, "attched"); HelloServiceGrpc.HelloServiceBlockingStub s=MetadataUtils.attachHeaders(blockingStub,meta); System.out.println(s.simpleHello(person).getString()); //关闭originalChannel originalChannel.shutdown().awaitTermination(5, TimeUnit.SECONDS); } }----服务端输出---- header received from client:Metadata(content-type=application/grpc,user-agent=grpc-java-netty/1.2.0,clientheader=request,grpc-accept-encoding=gzip,grpc-census-bin=) World calling header received from client:Metadata(content-type=application/grpc,user-agent=grpc-java-netty/1.2.0,attached_header=attched,grpc-accept-encoding=gzip,grpc-census-bin=) World calling----客户端输出---- header received from server:Metadata(content-type=application/grpc,serverheader=response,grpc-encoding=identity,grpc-accept-encoding=gzip) hello, World hello, World

这样在两端就可以看到对应的header
总结 通过header的内容可以对调用的流程进行一定的控制,以达到认证等功能。
【grpc拦截器】转载于:https://www.cnblogs.com/resentment/p/6818753.html

    推荐阅读