• 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)

  • 相关阅读:
    递归遍历多维数组(树数据结构)的超级简单方式,并且可以递归超过200层,摘自<<PHP精粹:编写高效PHP代码>>
    http协议传输二进制数据以及对输入流(php://input)和http请求的理解
    一个非常简单的RPC服务
    php://input 打开的数据流只能读取一次,即读取一次之后读取的值为空
    soap的简单实现(PHP)
    使用PHP的curl扩展实现跨域post请求,以及file_get_contents()百度短网址例子
    jquery选取iframe
    算法之棋盘覆盖
    词法分析之实验报告
    简单的词法分析小程序
  • 原文地址:https://www.cnblogs.com/ExMan/p/12269786.html
Copyright © 2020-2023  润新知