Protobuf简介
title: Protobuf语法
description:
published: true
date: 2024-11-09T07:40:56.593Z
tags:
editor: markdown
dateCreated: 2024-11-09T07:40:56.593Z
Proto3 是 Protocol Buffers 的第三版,是一种由 Google 开发的数据序列化格式。它被设计用来高效地描述结构化数据并提供跨语言的数据交换。Proto3 相较于之前版本 (proto2) 做了一些简化和改进:
- 去掉了可选和必需字段:
- proto3 中所有字段都默认是可选的,不再需要
optional
和required
关键字。 - 默认值:
- proto3 中所有标量字段都有默认值,例如
int32
的默认值为0
,string
的默认值为空字符串。 - 移除了一些 proto2 特性:
- proto3 去掉了默认值的显式设置、扩展、以及自定义选项等特性。
下面是 proto3 的语法和数据类型的详细介绍:
基本语法
1. 语法声明
必须在文件的开头声明使用 proto3 语法。
syntax = "proto3";
命名空间
option csharp_namespace = "GrpcServiceDemo";
2. 包声明
定义消息和服务所属的命名空间。
package example;
3. 导入其他 proto 文件
导入其他 proto 文件中的定义,可以是标准库中的文件或用户定义的文件。
import "google/protobuf/timestamp.proto";
import "google/protobuf/empty.proto";
4. 消息定义
消息类型用来定义数据结构,包含字段及其类型。
message SimpleMessage {
int32 id = 1;
string content = 2;
}
数据类型
Proto3 支持多种数据类型,主要包括以下几类:
1. 标量类型
| 类型 | 说明 |
|———-|——————————–|
| double
| 双精度浮点数 |
| float
| 单精度浮点数 |
| int32
| 32位有符号整数 |
| int64
| 64位有符号整数 |
| uint32
| 32位无符号整数 |
| uint64
| 64位无符号整数 |
| sint32
| 32位有符号整数(使用压缩编码) |
| sint64
| 64位有符号整数(使用压缩编码) |
| fixed32
| 32位定长有符号整数 |
| fixed64
| 64位定长有符号整数 |
| sfixed32
| 32位定长有符号整数 |
| sfixed64
| 64位定长有符号整数 |
| bool
| 布尔值 |
| string
| 字符串 |
| bytes
| 字节序列 |
2. 枚举类型
枚举类型用来定义一组命名常量。
enum EnumExample {
UNKNOWN = 0;
STARTED = 1;
RUNNING = 2;
FINISHED = 3;
}
3. 嵌套消息
message OuterMessage {
message InnerMessage {
int32 id = 1;
}
InnerMessage inner = 1;
}
消息类型可以嵌套定义。
4. 列表
使用 repeated
关键字定义列表字段。
message ListMessage {
repeated int32 values = 1;
}
5.字典
使用 map<key_type, value_type>
定义字典。
message DictionaryMessage {
map<string, string> dictionary = 1;
}
6. 特殊类型
google.protobuf.Timestamp
: 用来表示时间戳。google.protobuf.Duration
: 用来表示时间段。google.protobuf.Empty
: 空消息类型,通常用于无需请求或响应消息的场景。
7.字段标签
每个字段都有一个唯一的标签号,标签号在一个消息中必须唯一,并且应在1到2^29-1之间。以下是一些示例:
message Example {
int32 id = 1;
string name = 2;
repeated string tags = 3;
}
服务定义
服务用来定义 RPC 接口,可以包含一个或多个 RPC 方法。
service ExampleService {
rpc GetExample (ExampleRequest) returns (ExampleResponse);
}
三种流模式的使用场景
客户端流:
用于客户端需要连续发送多个请求,然后服务器根据所有请求消息返回一个响应的场景。
示例:文件上传、数据批量处理。
服务端流:
用于客户端发送一个请求,然后服务器连续返回多个响应消息的场景。
示例:实时数据推送、长时间运行的查询。
双向流:
用于客户端和服务器需要同时发送和接收消息的复杂交互场景。
示例:实时聊天、视频会议。
通过这些示例,可以更好地理解如何在 proto 文件中定义和使用 gRPC 的三种流模式。
客户端流(Client Streaming)
客户端流模式允许客户端发送一系列请求消息到服务器,服务器在收到所有请求消息后才返回一个响应消息。下面是一个客户端流模式的示例:
syntax = "proto3";
package example;
message RequestMessage {
int32 id = 1;
string content = 2;
}
message ResponseMessage {
string result = 1;
}
service ExampleService {
// 客户端流模式
rpc ClientStreaming (stream RequestMessage) returns (ResponseMessage);
}
在这个例子中,ClientStreaming
方法接收一个RequestMessage
类型的流,并返回一个ResponseMessage
类型的单一响应。
服务端流(Server Streaming)
服务端流模式允许服务器发送一系列响应消息到客户端,客户端在收到所有响应消息后才处理。下面是一个服务端流模式的示例:
syntax = "proto3";
package example;
message RequestMessage {
int32 id = 1;
string content = 2;
}
message ResponseMessage {
string result = 1;
}
service ExampleService {
// 服务端流模式
rpc ServerStreaming (RequestMessage) returns (stream ResponseMessage);
}
在这个例子中,ServerStreaming
方法接收一个RequestMessage
类型的单一请求,并返回一个ResponseMessage
类型的流。
双向流(Bidirectional Streaming)
双向流模式允许客户端和服务器之间进行双向的消息流,每一方都可以独立地发送和接收消息。下面是一个双向流模式的示例:
syntax = "proto3";
package example;
message RequestMessage {
int32 id = 1;
string content = 2;
}
message ResponseMessage {
string result = 1;
}
service ExampleService {
// 双向流模式
rpc BidirectionalStreaming (stream RequestMessage) returns (stream ResponseMessage);
}
在这个例子中,BidirectionalStreaming
方法接收一个RequestMessage
类型的流,并返回一个ResponseMessage
类型的流。
代码示例
下面是一个完整的 proto3 文件示例,涵盖了上述各种数据类型和语法特性:
syntax = "proto3";
package example;
import "google/protobuf/timestamp.proto";
import "google/protobuf/empty.proto";
enum Status {
UNKNOWN = 0;
ACTIVE = 1;
INACTIVE = 2;
}
message User {
int32 id = 1;
string name = 2;
bool is_active = 3;
Status status = 4;
google.protobuf.Timestamp last_login = 5;
map<string, string> metadata = 6;
}
message UserList {
repeated User users = 1;
}
service UserService {
rpc GetUser (User) returns (User);
rpc ListUsers (google.protobuf.Empty) returns (UserList);
rpc CreateUser (User) returns (User);
}
这个文件定义了一个简单的用户管理系统,包括用户的基本信息、状态、最后登录时间以及一些元数据,并定义了用户服务的三个方法:获取用户信息、列出所有用户以及创建新用户。