Protobuf对于Golang通过插件进行支持,因些需要安装protoc的执行环境,下面我们来一步步看下,如何搭建一个编译环境。
创新互联是网站建设专家,致力于互联网品牌建设与网络营销,专业领域包括成都做网站、网站建设、外贸营销网站建设、电商网站制作开发、重庆小程序开发、微信营销、系统平台开发,与其他网站设计及系统开发公司不同,我们的整合解决方案结合了恒基网络品牌建设经验和互联网整合营销的理念,并将策略和执行紧密结合,且不断评估并优化我们的方案,为客户提供全方位的互联网品牌整合方案!
1. 安装protoc
2. 下载并安装protobuf-Go插件
从github上下载插件,并解压(),得到以下的目录
[plain] view plain copy
drwxr-xr-x 6 root root 4096 Jun 16 15:45 .
drwxr-xr-x 3 root root 4096 Jun 16 15:48 ..
-rw-r--r-- 1 root root 173 Jun 15 06:31 AUTHORS
-rw-r--r-- 1 root root 170 Jun 15 06:31 CONTRIBUTORS
drwxr-xr-x 3 root root 4096 Jun 15 06:31 jsonpb
-rw-r--r-- 1 root root 1583 Jun 15 06:31 LICENSE
-rw-r--r-- 1 root root 2080 Jun 15 06:31 Makefile
-rw-r--r-- 1 root root 1955 Jun 15 06:31 Make.protobuf
drwxr-xr-x 4 root root 4096 Jun 15 06:31 proto
drwxr-xr-x 7 root root 4096 Jun 16 15:42 protoc-gen-go
drwxr-xr-x 8 root root 4096 Jun 15 06:31 ptypes
-rw-r--r-- 1 root root 7149 Jun 15 06:31 README.md
这时,执行make install,多半是不会成功的,一般会报找不到对应的文件,原因在于go源文件中指定的目录位置是这样的
之前写过了Grpc服务开发和接口测试初探【Java】,中间耽搁了一些时间,Go版本的gRPC测试开发实践才有时间学习使用。其中也是由于自己Go语言不够熟悉导致的。之前有段时间想暂时放弃Go语言的学习,导致了Go的生疏,原因是从Groovy到Java性能。
回归正题,Go语言版本的gRPC实践相对Java来说是比较简单的,但是总体的工具链是比较复杂的,可能是因为Go生态目前相比Java还是比较匮乏吧。下面我先简述一下大致的步骤:
以上步骤亲自操作可能会遇到一些小问题,我本人搜到的教程什么的也是乱七八糟,踩了一些坑。我没有整理出一个亲自实践之后的可行的教程,原因有二:
Go语言的gRPC的 proto 编写跟Java大致一致,只有一个报名的参数不太一样。下面是我的 Hello.proto 内容:
这里主要 go_package 网上搜到的配置方式有些不一样,我没有全都尝试,大家在搜索的资料时候,尽量先看看 syntax 这个参数的值,以及文章教程写作的时间,如果距离现在太久了,我建议直接关掉。搜索引擎有过滤功能,可以过滤掉过时的教程。
这里Go语言gRPC的一点优势,就是在一个项目中即可实现,Java需要先弄一个SDK这样。Go语言的gRPC的代码可以通过生成代码命令中的参数实现指定路径。我是放在了和 proto 文件的同级目录。
服务端代码也是比较格式化的内容,如下:
其中 pb.RegisterHelloServiceServer(s, Ser{}) 如果报错,请检查自己安装的工具 protoc-gen-go 或者 protoc-gen-gofast 版本,一般提取报错 message 搜索也能得到解决办法。
下面是客户端的代码,由于学艺不精,其中大部分参数的含义目前我也不是很清楚,特别是基于 stream 的请求响应的方式使用。后面我先把Java的学完,再回过头来看Go的,按照这个顺序学习和分享。
服务端输出:
忘记打日志了。没有输出
客户端输出:
Go语言的gRPC测试开发实践已经完事儿,大概率上我不会在工作中使用Go作为主力gRPC测试语言,后面测试实践内容还是会以Java为主。
因为在一些场景中指针表示的含义是比类型表示的多的
假设上述结构体表示一个用户的信息,创建用户后希望更新用户名时该怎么实现?这里隐藏的一个问题就是: address 为空字符串时,到底是表示不更新该字段?还是表示将该字段置为空?
使用指针的意义就是该字段可以额外表示一重含义
protoc : libprotoc 3.17.3
protoc-gen-go : 1.5.2
optional 对于 protoc 和 protoc-gen-go 的版本都是有依赖的,在低版本中还需要带上额外字段
[需要带上--experimental_allow_proto3_optional]( protocol buffers - How to define an optional field in protobuf 3 - Stack Overflow )
使用上面同样的 protoc 文件,发现是无法支持的
在 gogo/protobuf 还未支持 optional 的语法,一种可行的解法就是在 proto3 中导入 proto2 的文件,并且把需要定义为指针的字段放在 proto2 中
不过在网络上很难找到 wktptr 的介绍,这个语法也非常让人困惑
nullable 扩展字段无法支持原生类型,此扩展字段对此是无效的
这样可以将需要定义为指针的元素定义到 proto2 中然后内嵌进来