nd may not be reset.")
}
o.streamInt = i
})
}
然后使用返回的 grpc.ServerOption 值作为参数提供给 grpc.NewServer 函数以注册为 UnaryServerInterceptor。
下面是 StreamServerInterceptor func 类型的定义:
type StreamServerInterceptor func(srv interface{}, ss ServerStream, info *StreamServerInfo, handler StreamHandler) error
我们看下服务端流式拦截器的具体例子:
type wrappedStream struct {
grpc.ServerStream
}
func (w *wrappedStream) RecvMsg(m interface{}) error {
log.Printf("====== [Server Stream Interceptor] " +
"Receive a message (Type: %T) at %v",
m, time.Now().Format(time.RFC3339))
return w.ServerStream.RecvMsg(m)
}
func (w *wrappedStream) SendMsg(m interface{}) error {
log.Printf("====== [Server Stream Interceptor] " +
"Send a message (Type: %T) at %v",
m, time.Now().Format(time.RFC3339))
return w.ServerStream.SendMsg(m)
}
func newWrappedStream(s grpc.ServerStream) grpc.ServerStream {
return &wrappedStream{s}
}
func ServerStreamInterceptorCustom() grpc.ServerOption {
serverInterceptor := func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
return handler(srv, newWrappedStream(ss))
}
return grpc.StreamInterceptor(serverInterceptor)
}
上面服务端流式拦截器代码可参考客户端流式拦截器的代码,基本差不多。
3、多拦截器
go-grpc在v1.28.0之前是不支持多个拦截器。但是可以使用一些第三方的包,拦截器链接允应用多个拦截器。
v1.28.0之后已经可以支持多个拦截器,我们修改下服务端代码如下:
...
unaryInterceptors := []grpc.ServerOption {
ServerUnaryInterceptorCustom(),
ServerStreamInterceptorCustom(),
}
grpcServer := grpc.NewServer(unaryInterceptors...)
...