一、protobuf简介
Protocol Buffers,是Google公司开发的一种数据描述语言,类似于XML能够将结构化数据序列化,可用于数据存储、通信协议等方面。
关于相关工具的安装网上很多资料了,这里不再赘述。但是有几点需要注意的,protoc的版本要3.x.x;另外需要安装
protoc-gen-go
和protoc-gen-go-grpc
。
二、proto文件
先上示例代码
// calc.proto
syntax="proto3";
package calc;
option go_package="./calc";
import "calcRequest.proto";
message String {
string str = 1;
}
message SInt{
sint32 num = 1;
}
message Empty{
}
service Calc{
rpc Sum(CalcRequest) returns(SInt);
rpc Version(Empty) returns(String);
}
// calcRequest.proto
syntax="proto3";
package calc;
option go_package="./calc";
message CalcRequest{
sint32 a = 1;
sint32 b = 2;
}
可以看到这里分了两个文件,calc.proto
和calcRequest.proto
,其实一个文件也可以,这边分开的目的主要是为了展示多个文件的用法。
其实 proto 文件定义相对简单,下面就一些关键字介绍下:
- syntax:标识protobuf版本,这边是proto3
- package:区别不同的包
- option:选项,上面示例中表示的是生成的go代码会使用的包名
- message:类似结构体,格式为 变量类型 + 变量名 +
=
+ 序号; - service:定义具体的rpc接口,格式为
rpc
+ 方法名 +(
+ 入参 +)
+returns
+ 返回类型。这里需要注意,入参和出参一定要有,并且只能有一个。
三、生成代码
示例的文件结构为:
生成代码的命令为:
protoc -I./proto --go_out=. --go-grpc_out=. .\proto\*.proto
执行后在calc目录下生成3个文件分别为calc.pb.go
、calc_grpc.pb.go
、calcRequest.pb.go
在calc_grpc.pb.go
中有个接口
type CalcServer interface {
Sum(context.Context, *CalcRequest) (*SInt, error)
Version(context.Context, *Empty) (*String, error)
mustEmbedUnimplementedCalcServer()
}
这里是对应我们上面calc.proto
中定义的rpc,需要自己实现接口。
在calc目录下新建文件calcServer.go
package calc
import "context"
const version = "V1.0.0"
type Server struct {
UnimplementedCalcServer
}
func (Server) Sum(ctx context.Context, request *CalcRequest) (*SInt, error) {
return &SInt{Num: request.GetA() + request.GetB()}, nil
}
func (Server) Version(ctx context.Context, empty *Empty) (*String, error) {
return &String{Str: version}, nil
}
func (Server) mustEmbedUnimplementedCalcServer() {}
grpc相关代码至此已经准备完毕,下篇介绍具体使用方法。