前言

上篇文章《Go - 如何编写 ProtoBuf 插件 (二) 》,分享了基于 自定义选项 定义了 interceptor 插件,然后在 helloworld.proto 中使用了插件,最后在 golang 代码中获取到使用的插件信息。

接上篇,继续分享。

既然获取到了插件信息,我们就可以使用它们。本文主要分享在 grpc.ServerOption 中的 grpc.UnaryInterceptor 中使用。

演示代码

还是以上篇文章中 helloworld.proto 为例。

  1. // 生成 helloworld.pb.go
  2. // 生成 helloworld_grpc.pb.go
  3. // 使用的 protoc --version 为 libprotoc 3.18.1
  4. // 使用的 protoc-gen-go --version 为 protoc-gen-go v1.27.1
  5. // 使用的 protoc-gen-go-grpc --version 为 protoc-gen-go-grpc 1.1.0
  6. // 在根目录下执行 protoc 命令
  7. protoc --go_out=helloworld/gen --go-grpc_out=helloworld/gen helloworld/helloworld.proto

一、基于上篇文章中获取 options 的代码进行修改,主要是将其存入到结构体即可。

  1. // 演示代码,结构体
  2. var handlers = &struct {
  3. Methods map[string]*options.MethodHandler // FullMethod : Handler
  4. Services map[string]*options.ServiceHandler // FullMethod : Handler
  5. }{
  6. Methods: make(map[string]*options.MethodHandler),
  7. Services: make(map[string]*options.ServiceHandler),
  8. }

二、在 grpc.NewServer 中使用拦截器。

  1. // 演示代码
  2. serverOptions := []grpc.ServerOption{
  3. grpc.UnaryInterceptor(unaryServerInterceptor()),
  4. }
  5. srv := grpc.NewServer(serverOptions...)
  6. resolveFileDescriptor() // 解析 options 扩展项

三、在 unaryServerInterceptor() 方法中,可以根据当前请求的服务名和方法名获取到对应设置的 options

  1. // 演示代码
  2. fullMethod := strings.Split(info.FullMethod, "/")
  3. serviceName := fullMethod[1]
  4. // 获取 service options
  5. getServiceHandler(serviceName)
  6. // 获取 method options
  7. getMethodHandler(info.FullMethod)

四、自己写一个 grpcclient 调用一下即可。

  1. --- /helloworld.Greeter/SayHello1 ---
  2. service use interceptor authorization: login_token
  3. method use interceptor whitelist: ip_whitelist
  4. method use interceptor logger: true

至此,在 grpc.UnaryInterceptor 中就可以获取到 options 了,其他演示代码我就不贴了。

最后,通过获取到的 options,便可以执行自己定义的具体方法。

小结

通过最近的 “如何编写 ProtoBuf 插件” 这三篇文章,相信你对编写 ProtoBuf 插件有一点小的认识,希望对你能够有所帮助。

推荐阅读