message
protobuf中定义一个消息类型是通过关键字message字段指定。
消息就是需要传输的数据格式的定义,它类似java中的class,go中的struct
message User{
string username=1;
int32 age=2;
}
对应生成go的结构体
type User struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"`
Age int32 `protobuf:"varint,2,opt,name=age,proto3" json:"age,omitempty"`
}
在消息中承载的数据分别对应的每一个字段,其中每个字段都有一个名字和类型。
字段规则
- required 必填字段,不设置会导致编码解码异常
- optional 消息可选字段
- repeated 可重复字段,重复的值的顺序会被保留,在go中重复的会被定义为切片
message UserNew{
string username=1; // required字段,可以不填
int32 age=2;
optional string password=3;
repeated string addresses=4;
}
生成的格式如下:
字段映射
默认值
protobuf3删除了protobuf2中用来设置默认值的default关键字,取而代之的是为各种类型定义的默认值
标识号
在消息体的定义中,每个字段都必须要有一个唯一的标识号,标识号是[0,2^29-1]范围内的一个整数
message UserNew{
string username=1; // required字段,可以不填
int32 age=2;
optional string password=3;
repeated string addresses=4;
}
以上为例,username=1,age=2就是标识号
定义多个消息类型
一个proto文件可以定义多个消息类型
message User{
string username=1;
int32 age=2;
}
message UserNew{
string username=1; // required字段,可以不填
int32 age=2;
optional string password=3;
repeated string addresses=4;
}
嵌套消息
可以在其他消息类型中定义,使用消息类型,如下所示中Person消息就是定义在Persioninfo消息内
message PersonInfo{
message Person{
string name=1;
int32 height=2;
repeated int32 weight=3;
}
repeated Person info=1;
}
//父消息类型外部重用这个消息类型,如下使用
message PersonMessage{
PersonInfo.Person info=1;
}
嵌套多层消息
message Grandpa { //level 0
message Father{ //level 1
message son { //level 2
string name=1;
int32 age=2;
}
}
message Uncle { //level1
message Son{ //level2
string name=1;
int32 age=2;
}
}
}
定义服务service
如果要将消息类型用到RPC系统中,可以在proto文件中定义一个RPC服务接口,protocol buffer编译器会将根据选择不同的语言生成不同的服务接口代码
service SearchService{
//rpc 服务的函数名(传入参数)返回(返回参数)
rpc Search (SearchRequest) returns (SearchReaponse);
}
上述表示,定义了一个RPC服务,该方法接收SearchRequest返回SearchResponse