一. protobuf环境配置
注意根据电脑的版本下载,这里使用的是 protoc-3.19.4-win64.zip,下载完成后解压,进入bin目录中发现有一个protoc.exe二进制文件;
将这个bin地址添加到环境变量中.
验证安装:在cmd中输入protoc --version查看
2.安装protobuf插件
执行完成后在GOPATH/bin下会生成protoc-gen-go.exe和protoc-gen-go-grpc.exe文件,安装完成.
之前版本可以通过go get命令安装.
二.编写proto文件test.proto
protobuf文件规范参考官网.
三.通过插件生成go代码
在test.proto中定义了一个grpc服务,在test.proto所在的目录中执行:
发现在本目录下会生成两个.go文件:test.pb.go和test_grpc.pb.go,结构如下:
四.go文件解读
1.test.pb.go:
在test.pb.go文件中可以看到定义了两个结构体Student和Class,以及一些它们各自对应的方法,对比test.proto文件可以发现,正是我们用message关键字定义的两个消息体,而且结构体中也包含着消息体中对应的字段,其它内容感兴趣的可以自己研究.
2.test_grpc.pb.go:
FindClass是test.proto中定义的服务名称,MyClass是服务中使用的方法.
client部分定义了一个包含MyClass方法的接口.NewFindClassClient函数用于初始化grpc的客户端,可以看到其返回正是上边定义的接口类型,这就使初始化后的客户端可以直接调用findClassClient结构体的MyClass方法.
server部分同样也定义了一个包含MyClass方法的接口,接口中还包含了一个内部方法,此处不做分析.RegisterFindClassServer函数用于服务注册,其参数分别为一个grpc服务和一个FindClassServer接口类型.
五.grpc服务端
六.grpc客户端
七.注意事项
1. 由于版本问题,在通过proto文件生成.go文件时,之前可以通过: protoc --go_out=plugins=grpc:./ test.proto 来生成test_grpc.pb.go文件,最新版本此方法以及废弃,需要通过protoc --go-grpc_out=./ test.proto来实现;
2.在编写服务端时,之前的版本可以直接定义一个空结构体去注册服务,但在新版本中,如果直接new一个空结构体会编译失败:
错误如下:
Cannot use 'new(Teacher)' (type *Teacher) as the type FindClassServerType does not implement 'FindClassServer' as some methods are missing:mustEmbedUnimplementedFindClassServer()
可以看到是缺少mustEmbedUnimplementedFindClassServer()方法,在test_grpc.pb.go中也可以看到FindClassServer接口中确实包含了两个方法:
3.如果你使用的编辑器是goland2021.3版本,会发现在test.pb.go文件中有两处标红的地方:
错误信息如下:
Cannot use 'ms' (type *messageState) as the type protoreflect.MessageType does not implement 'protoreflect.Message'need the method: ProtoMethods() *methodshave the method: ProtoMethods() *protoiface.Methods
查了部分资料还是没得到明确的处理方法,有人说是goland2021.3的问题,不知道其他同学有没有遇到同样的问题,参考: https://github.com/grpc/grpc-go/issues/4980.