前言

上篇文章《Go - 如何编写 ProtoBuf 插件 (一) 》,分享了使用 proto3自定义选项 可以实现插件的编写,说到基于 MethodOptionsServiceOptions 选项去实现 methodservice 自定义设置拦截器。

接上篇文章,继续分享。

定义插件

// plugin/interceptor/options/interceptor.proto

syntax = "proto3";

package interceptor;

option go_package = "./;interceptor/options";

import "google/protobuf/descriptor.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.Println("--- 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.SayHello2
use interceptor logger: false
--- method ---

小结

本文主要内容是基于 自定义选项 定义了 interceptor 插件,然后在 helloworld.proto 中使用了插件,最后在 golang 代码中获取到使用的插件信息。

接下来,要对获取到的插件信息进行使用,主要用在 grpc.ServerOption 中,例如在 grpc.UnaryInterceptorgrpc.StreamInterceptor 中使用。

推荐阅读

Go - 如何编写 ProtoBuf 插件(二)?的更多相关文章

  1. Go - 如何编写 ProtoBuf 插件 (三) ?

    目录 前言 演示代码 小结 推荐阅读 前言 上篇文章<Go - 如何编写 ProtoBuf 插件 (二) >,分享了基于 自定义选项 定义了 interceptor 插件,然后在 hell ...

  2. [翻译]如何编写GIMP插件(二)

    写在前面: 本人翻译并不专业,甚至英语不好,翻译内容仅供参考.由于博主是边学边翻译,所以不能保证翻译的准确性和正确性,如果可以,请查看原版学习,本文仅作学习记录之用. <How to write ...

  3. 编写jQuery插件--实现返回顶部插件

    国庆过去一周多了,作为IT界的具有严重’工作狂‘性质的宅人,居然还没走出玩耍的心情,拖了程序猿的脚后跟了.最近工作不顺,心情不佳,想吐槽下公司,想了还是厚道点,以彼之道还施彼身,觉得自己也和他们同流合 ...

  4. 使用Qt编写模块化插件式应用程序

    动态链接库技术使软件工程师们兽血沸腾,它使得应用系统(程序)可以以二进制模块的形式灵活地组建起来.比起源码级别的模块化,二进制级别的模块划分使得各模块更加独立,各模块可以分别编译和链接,模块的升级不会 ...

  5. [翻译]如何编写GIMP插件(一)

    近期想尝试编写gimp插件,在gimp官网看到了三篇简明教程,顺便翻译了下,由于本人英文,计算机知识有限,文中难免有warning,error出现,欢迎指正. <How to write a G ...

  6. Lua编写wireshark插件初探——解析Websocket上的MQTT协议

    一.背景 最近在做物联网流量分析时发现, App在使用MQTT协议时往往通过SSL+WebSocket+MQTT这种方式与服务器通信,在使用SSL中间人截获数据后,Wireshark不能自动解析出MQ ...

  7. 金蝶K3 wise 插件二次开发与配置

    金蝶K3 wise 插件二次开发与配置 开发环境:K/3 Wise 13.0.K/3 Bos开发平台.Visual Basic 6.0 目录 一.二次开发插件编程二.代码演示三.配置插件四.测试插件五 ...

  8. 前端html、CSS快速编写代码插件-Emmet使用方法技巧详解

    前端html.CSS快速编写代码插件-Emmet使用方法技巧详解   Emmet的前身是大名鼎鼎的Zen coding,如果你从事Web前端开发的话,对该插件一定不会陌生.它使用仿CSS选择器的语法来 ...

  9. Qt 显示透明flash和编写QtWebkit插件

    Qt 有两种方法可以显示flash. 1. 通过QAxWidget 调用com形式显示flash, 需要本机安装IE flash插件 2. 直接通过qwebview显示flash, 需要下载webki ...

随机推荐

  1. [gym102832J]Abstract Painting

    考虑每一个圆即对应于区间$[x_{i}-r_{i},x_{i}+r_{i}]$,可以看作对于每一个区间,要求所有右端点严格比其小的区间不严格包含左端点 用$f_{i}$表示仅考虑右端点不超过$i$的区 ...

  2. [atARC094F]Normalization

    考虑$s$能变成$t$的必要条件(假设$s\ne t$): 1.$s$中存在一对相邻字符不同 2.$|s|=|t|$且若将a-c对应为0-2,则字符模3同余: 3.$t$中存在一对相邻两个字符相同 同 ...

  3. [bzoj1135]Lyz

    可以看成一张二分图,判断左半部分是否存在完美匹配根据hall定理,当且仅当左半部分每一个子集所连向的点数量超过了这个子集的大小都判定复杂度肯定爆炸,可以贪心,一定选择的是一个区间,即对于任意区间[l, ...

  4. 深度揭秘Netty中的FastThreadLocal为什么比ThreadLocal效率更高?

    阅读这篇文章之前,建议先阅读和这篇文章关联的内容. 1. 详细剖析分布式微服务架构下网络通信的底层实现原理(图解) 2. (年薪60W的技巧)工作了5年,你真的理解Netty以及为什么要用吗?(深度干 ...

  5. js--迭代器总结

    前言 我们已经熟练使用set.map.array几种集合类型了,掌握了map(),for..of..,filter()等迭代集合的方法,你是否思考过,js引擎是怎么迭代的,怎么判断迭代是否结束,本文来 ...

  6. Spring Cloud Alibaba微服务一站式解决方案-开篇v2.2.1.RELEASE

    学习路线 **本人博客网站 **IT小神 www.itxiaoshen.com 生态概述 架构演进 什么是微服务 https://martinfowler.com/microservices/ Mic ...

  7. CF513G3 Inversions problem

    考虑记\(f_{i,j,k}\)为\(k\)次操作后,\(i,j\)位置被调换的概率. 那么我们考虑枚举我们要算的答案即\((x,y)\). 那么有\(\frac{n * (n + 1)}{2}\)种 ...

  8. 混合(Pooling)样本测序研究

    目录 1.混合测序基础 2. 点突变检测 3. BSA 4. BSR 5. 混合样本GWAS分析 6. 混合样本驯化研究 7. 小结 1.混合测序基础 测序成本虽然下降了,但对于植物育种应用研究来说还 ...

  9. 【机器学习与R语言】3-概率学习朴素贝叶斯(NB)

    目录 1.理解朴素贝叶斯 1)基本概念 2)朴素贝叶斯算法 2.朴素贝斯分类应用 1)收集数据 2)探索和准备数据 3)训练模型 4)评估模型性能 5)提升模型性能 1.理解朴素贝叶斯 1)基本概念 ...

  10. WSL + MobaXterm 取代虚拟机

    windows子系统安装默认C盘,这里我们直接下载安装文件安装在我们指定的目录. 1.先去官方网站下载安装文件:https://docs.microsoft.com/zh-cn/windows/wsl ...