跳到主要内容

自定义拦截器

如果框架自带的拦截器都没有满足需求的,则可以自定义或者使用社区提供的拦截器。

自定义server中间件

步骤一:编写拦截器

import (
...
grpc2 "google.golang.org/grpc"
...
)
func UnaryServerInterceptorDemo() grpc2.UnaryServerInterceptor {
return func(ctx context.Context, req interface{}, info *grpc2.UnaryServerInfo, handler grpc2.UnaryHandler) (_ interface{}, err error) {

fmt.Println("======= demo before=======")
defer func() {
if err := recover(); err != nil {
//打印错误堆栈信息
fmt.Println(err)

}
}()

resp, err := handler(ctx, req)

fmt.Println("======= demo after=======")

return resp, err
}
}

步骤二:将拦截器加入到server中

import (
"github.com/go-eagle/eagle/pkg/transport/grpc"
)
grpcServer := grpc.NewServer(
grpc.Network("tcp"),
grpc.Address(":9000"),
grpc.Timeout(3*time.Second),
grpc.UnaryInterceptor(UnaryServerInterceptorDemo()),
)

到此自定义拦截器开发完毕,这里需要注意拦截器的顺序问题。

拦截器顺序demo

import (
...
grpc2 "google.golang.org/grpc"
...
)

func UnaryServerInterceptorDemo() grpc2.UnaryServerInterceptor {
return func(ctx context.Context, req interface{}, info *grpc2.UnaryServerInfo, handler grpc2.UnaryHandler) (_ interface{}, err error) {

fmt.Println("======= demo before=======")
defer func() {
if err := recover(); err != nil {
//打印错误堆栈信息
fmt.Println(err)

}
}()

resp, err := handler(ctx, req)

fmt.Println("======= demo after=======")

return resp, err
}
}

func UnaryServerInterceptorDemo2() grpc2.UnaryServerInterceptor {
return func(ctx context.Context, req interface{}, info *grpc2.UnaryServerInfo, handler grpc2.UnaryHandler) (_ interface{}, err error) {

fmt.Println("======= demo2 before=======")

defer func() {
if err := recover(); err != nil {
//打印错误堆栈信息
fmt.Println(err)

}
}()

resp, err := handler(ctx, req)

fmt.Println("======= demo2 after=======")
return resp, err
}
}

输出结果

======= demo before=======
======= demo2 before======
======= demo2 after=======
======= demo after========