Go - 如何编写 ProtoBuf 插件(二)?
2021-12-18 15:26
966 查看
目录
前言
上篇文章《Go - 如何编写 ProtoBuf 插件 (一) 》,分享了使用
proto3的
自定义选项可以实现插件的编写,说到基于
MethodOptions和
ServiceOptions选项去实现
method和
service自定义设置拦截器。
接上篇文章,继续分享。
定义插件
// plugin/interceptor/options/interceptor.proto syntax = "proto3"; package interceptor; option go_package = "./;interceptor/options"; import "google/protobuf/descriptor ad8 .proto"; extend google.protobuf.MethodOptions { optional MethodHandler method_handler = 63500; } extend google.protobuf.ServiceOptions { optional ServiceHandler service_handler = 63501; } message MethodHandler { optional string authorization = 1; // login token optional string whitelist = 2; // ip whitelist optional bool logger = 3; // logger } message ServiceHandler { optional string authorization = 1; // login token optional string whitelist = 2; // ip whitelist optional bool logger = 3; // logger }
接下来根据
interceptor.proto生成
interceptor.pb.go
// 生成 interceptor.pb.go // 使用的 protoc --version 为 libprotoc 3.18.1 // 使用的 protoc-gen-go --version 为 protoc-gen-go v1.27.1 // 在 plugin/interceptor/options 目录下执行 protoc 命令 protoc --go_out=. interceptor.proto
使用插件
// helloworld/helloworld.proto syntax = "proto3"; package helloworld; option go_package = "./;helloworld"; import "plugin/interceptor/options/interceptor.proto"; service Greeter { option (interceptor.service_handler) = { authorization : "login_token", }; rpc SayHello1 (HelloRequest) returns (HelloReply) { option (interceptor.method_handler) = { whitelist : "ip_whitelist", logger: true, }; } rpc SayHello2 (HelloRequest) returns (HelloReply) { option (interceptor.method_handler) = { logger: false, }; } } message HelloRequest { string name = 1; } message HelloReply { string message = 1; }
接下来根据
helloworld.proto生成
helloworld.pb.go
// 生成 helloworld.pb.go // 使用的 protoc --version 为 libprotoc 3.18.1 // 使用的 protoc-gen-go --version 为 protoc-gen-go v1.27.1 // 在根目录下执行 protoc 命令 protoc --go_out=helloworld/gen helloworld/helloworld.proto
获取自定义选项
// main.go // 演示代码 package main import ( "fmt" "strconv" _ "github.com/xinliangnote/protobuf/helloworld/gen" "github.com/xinliangnote/protobuf/plugin/interceptor/options" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoregistry" ) func main() { protoregistry.GlobalFiles.RangeFiles(func(fd protoreflect.FileDescriptor) bool { services := fd.Services() for i := 0; i < services.Len(); i++ { service := services.Get(i) if serviceHandler, _ := proto.GetExtension(service.Options(), options.E_ServiceHandler).(*options.ServiceHandler); serviceHandler != nil { fmt.Println() fmt.Prin 56c tln("--- service ---") fmt.Println("service name: " + string(service.FullName())) if serviceHandler.Authorization != nil && *serviceHandler.Authorization != "" { fmt.Println("use interceptor authorization: " + *serviceHandler.Authorization) } fmt.Println("--- service ---") } methods := service.Methods() for k := 0; k < methods.Len(); k++ { method := methods.Get(k) if methodHandler, _ := proto.GetExtension(method.Options(), options.E_MethodHandler).(*options.MethodHandler); methodHandler != nil { fmt.Println() fmt.Println("--- method ---") fmt.Println("method name: " + string(method.FullName())) if methodHandler.Whitelist != nil && *methodHandler.Whitelist != "" { fmt.Println("use interceptor whitelist: " + *methodHandler.Whitelist) } if methodHandler.Logger != nil { fmt.Println("use interceptor logger: " + strconv.FormatBool(*methodHandler.Logger)) } fmt.Println("--- method ---") } } } return true }) }
输出:
--- service --- service name: helloworld.Greeter use interceptor authorization: login_token --- service --- --- method --- method name: helloworld.Greeter.SayHello1 use interceptor whitelist: ip_whitelist use interceptor logger: true --- method --- --- method --- method name: helloworld.Greeter.SayHel 56c lo2 use interceptor logger: false --- method ---
小结
本文主要内容是基于
自定义选项定义了
interceptor插件,然后在
helloworld.proto中使用了插件,最后在
golang代码中获取到使用的插件信息。
接下来,要对获取到的插件信息进行使用,主要用在
grpc.ServerOption中,例如在
grpc.UnaryInterceptor和
grpc.StreamInterceptor中使用。
推荐阅读
相关文章推荐
- 使用CSharp编写Google Protobuf插件
- 使用CSharp编写Google Protobuf插件
- 步步教你如何在linux安装protobuf插件图文--适合菜鸟初学者
- 如何在Go中使用Protobuf
- TarsGo新版本发布,支持protobuf,zipkin和自定义插件
- 在Qt中如何编写插件,加载插件和卸载插件
- 全图文分析:如何利用Google的protobuf,来思考、设计、实现自己的RPC框架
- SQL Server:如何编写SSMS插件
- 怎么样编写Protobuf的.proto文件
- go get 找不到 google.golang.org/protobuf 解决办法
- 如何用正确的姿势编写jQuery插件
- protobuf如何用proto文件导出C++代码文件及链接protobuf静态库问题
- google protobuf 的 visual studio 2008 的语法高亮插件
- 如何编写自己的插件?
- 如何编译安装protobuf极其python版本
- 如何编写训练测试的prototxt配置文件---以Resnet为例
- 如何编写一个gulp插件
- jQuery插件如何编写02_ 简单的全选插件
- 如何编写一个使用Store更新复选框的CheckboxGroup的插件
- go语言 microservices微服务(二)=>Go micro框架和Google Protocol Buffer(Protobuf)