golang grpc UnaryServerInterceptor用法
有的时候,当进行grpc调用的时候,并不希望客户端与服务端建立连接后直接就进入对应的方法体内。比如需要验证签名来确认客户端的身份,再执行相应的方法。这个时候就可以哟拿到Interceptor。
拦截器的分类
在gRPC中有两种拦截器UnaryInterceptor
和StreamInterceptor
,其中UnaryInterceptor拦截普通的一次请求一次响应的rpc服务,StreamInterceptor拦截流式的rpc服务。
Server
在包google.golang.org/grpc
中,给Server提供了两个适用于Unary和Stream的拦截器函数分别是UnaryInterceptor
和StreamInterceptor
UnaryInterceptor
golang grpc的拦截器(Interceptor)为UnaryServerInterceptor,为一个指向函数的指针。
UnaryServerInterceptor在服务端对于一次RPC调用进行拦截。UnaryServerInterceptor是一个函数指针,当客户端进行grpc调用的时候,首先并不执行用户调用的方法,先执行UnaryServerInterceptor所指的函数,随后再进入真正要执行的函数。
grpc的UnaryServerInterceptor定义如下:
// UnaryServerInterceptor provides a hook to intercept the execution of a unary RPC on the server. info
// contains all the information of this RPC the interceptor can operate on. And handler is the wrapper
// of the service method implementation. It is the responsibility of the interceptor to invoke handler
// to complete the RPC.
type UnaryServerInterceptor func(ctx context.Context, req interface{}, info *UnaryServerInfo, handler UnaryHandler) (resp interface{}, err error)
req就是用户的请求参数,info中包含了此次调用的信息,handler就是客户端此次实际要调用的函数。
UnaryServerInfo的定义如下:
// UnaryServerInfo consists of various information about a unary RPC on
// server side. All per-rpc information may be mutated by the interceptor.
type UnaryServerInfo struct {
// Server is the service implementation the user provides. This is read-only.
Server interface{}
// FullMethod is the full RPC method string, i.e., /package.service/method.
FullMethod string
}
主要包含两个部分,Server成员,是客户编写的服务器端的服务实现,这个成员是只读的,FullMethod成员是要调用的方法名,这个方法名interceptor可以进行修改。所以说,如果需要进行服务端方法调用之前需要验签的话,interceptor可以这么写:
var interceptor grpc.UnaryServerInterceptor
interceptor = func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {
//对req中的签名进行验证
//如果失败直接返回Nil,err=验证签名失败
//handler是客户端原来打算调用的方法,如果验证成功,执行真正的方法
return handler(ctx, req)
}
相应的服务端初始化程序就是类似这种写法:
lis, err := net.Listen("tcp", fmt.Sprintf(":%s", port))
if err != nil {
panic(err)
return
}
var opts []grpc.ServerOption//grpc为使用的第三方的grpc包
opts = append(opts, grpc.UnaryInterceptor(interceptor))
server := grpc.NewServer(opts...)
chatprt.RegisterChatServer()//填入相关参数
server.Serve(lis)
相关文章
- golang gin ShouldBindQuery表单数据绑定: `form:“username“ binding:“required,min=3“`
- golang字符串类型:遍历字符串中的字符及修改字符串,只能转换为[]byte(字符串不含中文)或[]rune(字符串含中文)
- golang获取变量地址值和指针变量示例
- Go语言自学系列 | golang切片
- golang文件读写三种方式——bufio,ioutil和os.create
- GoLang笔记-数组和切片,本质是就是长度不可变的可变的区别
- golang ...用法
- Golang 程序中实现优雅关闭 HTTP SERVER
- golang面向对象分析
- Golang中sync.Map的实现原理
- [Golang] kafka集群搭建和golang版生产者和消费者
- golang channel 用法
- Golang gRPC实践 连载一 gRPC介绍与安装
- Golang学习笔记
- GoLang读写数据---下
- Golang基础知识入门详解