基本市面上所有框架都是支持拦截器的,gRPC也不例外。grpc支持客户端和服务端拦截以下是Java和go语言的实现。
syntax = "proto3";//标识 proto版本 建议使用proto3
package orderservice;//proto包名 避免命名冲突,也可以作为引入其他proto文件时使用
option java_package = "com.example.orderservice" ;//生成的类将带有此包名,不指定则使用package
option cc_generic_services = true;
option go_package = "./pb";
option java_outer_classname = "OrderPbEntity";
message GetOrderListReq{
string userId = 1;
}
message GetOrderListRes{
repeated string orderIds = 1;
}
message SearchOrderListReq{
string orderName = 1;
}
message SearchOrderListRes{
repeated string orderIds = 1;
}
service OrderService {
rpc getOrderList(GetOrderListReq) returns (GetOrderListRes);
}
package com.example.orderservice.impl;
import com.example.orderservice.OrderPbEntity;
import com.example.orderservice.OrderServiceGrpc;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import io.grpc.stub.StreamObserver;
import java.util.HashMap;
import java.util.List;
public class OrderServiceImpl extends OrderServiceGrpc.OrderServiceImplBase {
private HashMap<String, List<String>> data = Maps.newHashMap();
@Override
public void getOrderList(OrderPbEntity.GetOrderListReq request, StreamObserver<OrderPbEntity.GetOrderListRes> responseObserver) {
if (data.isEmpty()){
initData();
}
String userId = request.getUserId();
List<String> strings = data.get(userId);
responseObserver.onNext(OrderPbEntity.GetOrderListRes.newBuilder().addAllOrderIds(strings).build());
responseObserver.onCompleted();
}
private void initData() {
List<String> data1 = Lists.newArrayList();
data1.add("order_1");
data1.add("order_2");
data1.add("order_3");
data1.add("order_4");
data.put("1",data1);
data.put("2",data1);
}
}
OrderMsgServerCall
package com.example.orderservice.interceptors;
import io.grpc.ForwardingServerCall;
import io.grpc.MethodDescriptor;
import io.grpc.ServerCall;
import java.util.logging.Logger;
public class OrderMsgServerCall<ReqT, RespT> extends ForwardingServerCall.SimpleForwardingServerCall<ReqT, RespT> {
private static final Logger logger = Logger.getLogger(OrderMsgServerCall.class.getName());
OrderMsgServerCall(ServerCall<ReqT, RespT> delegate) {
super(delegate);
}
@Override
protected ServerCall<ReqT, RespT> delegate() {
return super.delegate();
}
@Override
public MethodDescriptor<ReqT, RespT> getMethodDescriptor() {
return super.getMethodDescriptor();
}
@Override
public void sendMessage(RespT message) {
logger.info("Message from Service -> Client : " + message);
super.sendMessage(message);
}
}
OrderMsgServerCallListener
package com.example.orderservice.interceptors;
import com.example.orderservice.OrderPbEntity;
import io.grpc.ForwardingServerCallListener;
import io.grpc.ServerCall;
import java.util.logging.Logger;
public class OrderMsgServerCallListener<R> extends ForwardingServerCallListener<R> {
private static final Logger logger = Logger.getLogger(OrderMsgServerCallListener.class.getName());
private final ServerCall.Listener<R> delegate;
OrderMsgServerCallListener(ServerCall.Listener<R> delegate) {
this.delegate = delegate;
}
@Override
protected ServerCall.Listener<R> delegate() {
return delegate;
}
@Override
public void onMessage(R message) {
if(message instanceof OrderPbEntity.GetOrderListReq){
OrderPbEntity.GetOrderListReq req = (OrderPbEntity.GetOrderListReq)message;
String userId = req.getUserId();
logger.info("userId:"+userId);
}
logger.info("Message Received from Client -> Service " + message);
super.onMessage(message);
}
}
ParamsInterceptor
package com.example.orderservice.interceptors;
import io.grpc.*;
import java.util.logging.Logger;
public class ParamsInterceptor implements ServerInterceptor {
Logger logger = Logger.getLogger(this.getClass().getName());
@Override
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> call, Metadata headers, ServerCallHandler<ReqT, RespT> next) {
logger.info("======= [Server Interceptor] : Remote Method Invoked - " + call.getMethodDescriptor().getFullMethodName());
ServerCall<ReqT, RespT> serverCall = new OrderMsgServerCall<>(call);
return new OrderMsgServerCallListener<>(next.startCall(serverCall, headers));
}
}
package com.example.orderservice;
import com.example.orderservice.impl.OrderServiceImpl;
import com.example.orderservice.interceptors.ParamsInterceptor;
import io.grpc.Server;
import io.grpc.ServerBuilder;
import io.grpc.protobuf.services.ProtoReflectionService;
import java.io.IOException;
public class App {
public String getGreeting() {
return "Hello World!";
}
public static void main(String[] args) throws IOException, InterruptedException {
System.out.println(new App().getGreeting());
Server server = ServerBuilder.forPort(10082).intercept(new ParamsInterceptor()).addService(new OrderServiceImpl())
.addService(ProtoReflectionService.newInstance())
.build();
server.start();
server.awaitTermination();
}
}
/*
* This Java source file was generated by the Gradle 'init' task.
*/
package com.examples.orderservice;
import com.example.orderservice.OrderPbEntity;
import com.example.orderservice.OrderServiceGrpc;
import io.grpc.*;
public class App {
public static void main(String[] args) {
ManagedChannel managedChannel = ManagedChannelBuilder.forAddress("localhost",10082)
.usePlaintext()
.build();
Channel channel = ClientInterceptors.intercept(managedChannel, new ClientInterceptor() {
@Override
public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(MethodDescriptor<ReqT, RespT> method, CallOptions callOptions, Channel next) {
System.out.println("method:"+method.getFullMethodName());
return next.newCall(method,callOptions);
}
});
OrderServiceGrpc.OrderServiceBlockingStub orderServiceBlockingStub = OrderServiceGrpc.newBlockingStub(channel);
OrderPbEntity.GetOrderListReq req = OrderPbEntity.GetOrderListReq.newBuilder().setUserId("1")
.build();
OrderPbEntity.GetOrderListRes orderList = orderServiceBlockingStub.getOrderList(req);
for (String orderId : orderList.getOrderIdsList()) {
System.out.println("orderId:"+orderId);
}
}
}