文档:https://godoc.org/github.com/grpc-ecosystem/go-grpc-middleware
gRPC是一个非常棒的RPC中间件,它在Golang世界中被广泛采用。然而,上游的gRPC代码库相对比较简单。
这个包及其大部分子包为gRPC提供了通常需要的中间件:用于退休的客户端拦截器、用于输入验证和验证的服务器端拦截器、用于链接所述拦截器的功能、元数据便利方法等等。
func ChainStreamClient(interceptors …grpc.StreamClientInterceptor) grpc.StreamClientInterceptor
- 从许多拦截器链中创建一个拦截器。执行按从左到右的顺序执行
func ChainStreamServer(interceptors …grpc.StreamServerInterceptor) grpc.StreamServerInterceptor
- 从许多拦截器链中创建一个拦截器。执行按从左到右的顺序执行
func ChainUnaryClient(interceptors …grpc.UnaryClientInterceptor) grpc.UnaryClientInterceptor
- 从许多拦截器链中创建一个拦截器。执行按从左到右的顺序执行
func ChainUnaryServer(interceptors …grpc.UnaryServerInterceptor) grpc.UnaryServerInterceptor
- 从许多拦截器链中创建一个拦截器。执行按从左到右的顺序执行
func WithStreamServerChain(interceptors …grpc.StreamServerInterceptor) grpc.ServerOption
func WithUnaryServerChain(interceptors …grpc.UnaryServerInterceptor) grpc.ServerOption
WithStreamServerChain,WithUnaryServerChain是为了简化代码的作用例如:s := grpc.NewServer(grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(grpc_auth.UnaryServerInterceptor(AuthInterceptor))))可以写为s := grpc.NewServer(grpc_middleware.WithUnaryServerChain(grpc_auth.UnaryServerInterceptor(AuthInterceptor)))
自定义拦截器,服务端:
package mainimport ("context""google.golang.org/grpc""google.golang.org/grpc/codes""google.golang.org/grpc/status""log""net"pb "study/grpc/protobuf/person""github.com/grpc-ecosystem/go-grpc-middleware")// 全局恐慌func RecoveryInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {defer func() {if e := recover(); e != nil {err = status.Errorf(codes.Internal, "Panic err: %v", e)}}()return handler(ctx, req)}// 日志记录func LoggingInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {log.Printf("gRPC method: %s, %v", info.FullMethod, req)resp, err := handler(ctx, req)log.Printf("gRPC method: %s, %v", info.FullMethod, resp)return resp, err}func main() {lis, err := net.Listen("tcp", port)if err != nil {log.Fatalf("failed to listen: %v", err)}opts := grpc_middleware.WithUnaryServerChain(RecoveryInterceptor, // 全局恐慌LoggingInterceptor, // 日志记录)s := grpc.NewServer(opts) //起一个服务pb.RegisterPersonserverServer(s,&Server{})if err := s.Serve(lis); err != nil {log.Fatalf("failed to serve: %v", err)}}
自定义拦截器,客户端:
func MyInterceptor() grpc.UnaryClientInterceptor{// 自己的处理逻辑return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {// 自己的处理逻辑return invoker(ctx, method, req, reply, cc, opts...)}}
