golang grpc UnaryServerInterceptor用法


有的時候,當進行grpc調用的時候,並不希望客戶端與服務端建立連接后直接就進入對應的方法體內。比如需要驗證簽名來確認客戶端的身份,再執行相應的方法。這個時候就可以喲拿到Interceptor。

 

攔截器的分類

在gRPC中有兩種攔截器UnaryInterceptorStreamInterceptor,其中UnaryInterceptor攔截普通的一次請求一次響應的rpc服務,StreamInterceptor攔截流式的rpc服務。

Server

在包google.golang.org/grpc中,給Server提供了兩個適用於Unary和Stream的攔截器函數分別是UnaryInterceptorStreamInterceptor

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)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM