【grpc03】proto文件介绍
目录
message介绍
字段规则
标识号
字段映射
默认值
定义多个消息类型
嵌套消息
定义服务(Service)
message介绍
- protobuf中定义一个消息类型是通过关键字
message
字段指定的。 消息就是需要传输的数据格式的定义。 - message关键字类似于C++中的class,Java中的class,go中的struct
- 在消息中承载的数据分别对应于每一个字段,其中每个字段都有一个名字和一种类型 。
- 一个proto文件中可以定义多个消息类型
字段规则
required
:消息体中必填字段,不设置会导致编解码异常。在protobuf2中使用,protobuf3被删除optional
: 消息体中可选字段。protobuf3没有了required,optional等说明关键字,都默认为optionalrepeated
: 消息体中可重复字段,重复的值的顺序会被保留在go中重复的会被定义为切片。
message User {
string username = 1;
int32 age = 2;
optional string password = 3;
repeated string address = 4;
}
标识号
在消息体的定义中,每个字段都必须要有一个唯一的标识号,标识号是[0,2^29-1]范围内的一个整数。
message Person {
string name = 1; // (位置1)
int32 id = 2;
optional string email = 3;
repeated string phones = 4; // (位置4)
}
以Person为例,name=1,id=2, email=3, phones=4 中的1-4就是标识号。
字段映射
proto Type | Notes | C++ Type | Python Type | Go Type |
---|---|---|---|---|
double | double | float | float64 | |
float | float | float | float32 | |
int32 | 使用变长编码,对于负值的效率很低,如果你的域有 可能有负值,请使用sint64替代 | int32 | int | int32 |
uint32 | 使用变长编码 | uint32 | int/long | uint32 |
uint64 | 使用变长编码 | uint64 | int/long | uint64 |
sint32 | 使用变长编码,这些编码在负值时比int32高效的多 | int32 | int | int32 |
sint64 | 使用变长编码,有符号的整型值。编码时比通常的 int64高效。 | int64 | int/long | int64 |
fixed32 | 总是4个字节,如果数值总是比总是比228大的话,这 个类型会比uint32高效。 | uint32 | int | uint32 |
fixed64 | 总是8个字节,如果数值总是比总是比256大的话,这 个类型会比uint64高效。 | uint64 | int/long | uint64 |
sfixed32 | 总是4个字节 | int32 | int | int32 |
sfixed32 | 总是4个字节 | int32 | int | int32 |
sfixed64 | 总是8个字节 | int64 | int/long | int64 |
bool | bool | bool | bool | |
string | 一个字符串必须是UTF-8编码或者7-bit ASCII编码的文 本。 | string | str/unicode | string |
bytes | 可能包含任意顺序的字节数据。 | string | str | []byte |
默认值
protobuf3 删除了 protobuf2 中用来设置默认值的 default 关键字,取而代之的是protobuf3为各类型定义的默认值,也就是约定的默认值,如下表所示:
类型 | 默认值 |
---|---|
bool | false |
整型 | 0 |
string | 空字符串"" |
枚举enum | 第一个枚举元素的值,因为Protobuf3强制要求第一个枚举元素的值必须是0,所以枚举的默认值就是0; |
message | 不是null,而是DEFAULT_INSTANCE |
定义多个消息类型
一个proto文件中可以定义多个消息类型
message UserRequest {
string username = 1;
int32 age = 2;
optional string password = 3;
repeated string address = 4;
}
message UserResponse {
string username = 1;
int32 age = 2;
optional string password = 3;
repeated string address = 4;
}
嵌套消息
可以在其他消息类型中定义、使用消息类型,在下面的例子中,Person消息就定义在PersonInfo消息内,如 :
message PersonInfo {
message Person {
string name = 1;
int32 height = 2;
repeated int32 weight = 3;
}
repeated Person info = 1;
}
如果你想在它的父消息类型的外部重用这个消息类型,你需要以PersonInfo.Person的形式使用它,如:
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 { // Level 1
message Son { // Level 2
string name = 1;
int32 age = 2;
}
}
}
定义服务(Service)
如果想要将消息类型用在RPC系统中,可以在.proto文件中定义一个RPC服务接口,protocol buffer 编译器将会根据所选择的不同语言生成服务接口代码及存根。
service SearchService {
//rpc 服务的函数名 (传入参数)返回(返回参数)
rpc Search (SearchRequest) returns (SearchResponse);
}
上述代表表示,定义了一个RPC服务,该方法接收SearchRequest返回SearchResponse