golang-protobuf入门记录

语法指南

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
// 语法标记,默认为proto2语法
// 必须位于文件开头非空非注释的第一行
syntax = "proto3";

// 以包声明开头,这有助于防止不同项目之间的命名冲突。
package coolcar;

// go_package选项定义了包的导入路径,该路径将包含此文件的所有生成代码。Go 包名称将是导入路径的最后一个路径组件
option go_package="coolcar/proto/gen/go/trippb";

// 消息体
// 消息体内每个字段都由一个字段类型、字段名称、字段编号组成
// 字段类型:float,int32,int64,uint32,uint64,bool,string,bytes,nested type(复合类型或嵌套类型)
// 字段编号:1~15编号使用一个字节编码,16~2047范围两个编码,因此应该为非常频繁出现的消息元素保留数字 1 到 15
// 数字 19000 到 19999是为 Protocol Buffers 实现保留的,不能使用
// 字段名称:使用小写加下划线,计量字段因带上计量单位,如:duration_sec(时长:秒),fee_cent(费用:分)
// 保留字段:如果需要更新功能时可以通过 reserved 保留某些字段名称或字段编号,这样就不会被重新使用了,protoc会检查。
message Location {
float latitude = 1;
float longitude = 2;
}


// 枚举
// 必须有一个零值,用于使用0作为默认数字
// 零值必须为第一个元素,以便与proto2语法兼容
// 通过设置 option allow_alias = true; 来为不同的枚举设置同样的值:如SUCCESS
// 常量数字必须在32位整数内,不推荐使用负数(编码低效)
// 枚举可以定义在消息体类,也可以在外面
// 保留字段:如果需要更新功能时可以通过 reserved 保留某些枚举字段或枚举常量,这样就不会被重新使用了,protoc会检查。
enum TripStatus {
// option allow_alias = true;
TS_NOT_SPECIFIED = 0;
NOT_STARTED = 1;
IN_PROGRESS = 2;
FINISHED = 3;
PAID = 4;
// SUCCESS = 4;
}

// 使用其他消息类型
// repeated 用于一个字段保存多个数据
// 关联映射 map<string, Project> projects = 3; map字段不能是repeated
message Trip {
string start = 1;
string end = 2;
Location start_pos = 5;
Location end_pos = 6;
repeated Location path_locations = 7;
int32 duration_sec = 3;
int32 fee_cent = 4;
TripStatus status = 8;
map<string, string> projects = 9;
}

// 导入定义
// import "myproject/other_protos.proto";

message GetTripRequest {
string id = 1;
}

message GetTripResponse {
string id = 1;
Trip trip = 2;
}

// 定义RPC服务接口
service TripService {
rpc GetTrip (GetTripRequest) returns (GetTripResponse);
}

编译.proto文件

  1. 首先安装protobuf
    按照系统下载让后安装并加入系统变量
    1
    2
    https://github.com/protocolbuffers/protobuf/releases

  2. 安装protobuf的golang插件
    编译器插件protoc-gen-go将安装在 中 $GOBIN
    1
    2
    3
    go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
    #grpc服务需要
    go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
  3. 运行编译器
    $SRC_DIR源码目录,不指定则为当前目录。$DST_DIR输出目录
    1
    2
    3
    4
    #格式
    protoc -I=$SRC_DIR --go_out=$DST_DIR $SRC_DIR/addressbook.proto
    #demo
    protoc -I=. --go_out=paths=source_relative:gen/go --go-grpc_out=paths=source_relative:gen/go trip.proto

–go_out参数说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
--go_out参数用来指定 protoc-gen-go 插件的工作方式和go代码的生成位置

--go_out主要的两个参数为 plugins 和 paths,分别表示生成go代码所使用的插件和生成的go代码的位置。

--go_out的写法是参数之间用 逗号 隔开,最后加上 冒号 来指定代码的生成位置。

比如:--go_out=plugins=grpc,paths=import:.

paths参数有两个选项,分别是 import 和 source_relative。
默认为 import,表示按照生成的go代码的包的全路径去创建目录层级,
source_relative 表示按照proto源文件的目录层级去创建go代码的目录层级。

例:

option go_package="proto/pb_go";

# 指令1:paths为import,pb文件最终在 pb_go 目录下
$ protoc --proto_path=. --go_out=. proto/greeter/greeter.proto
$ protoc --proto_path=. --go_out=paths=import:. proto/greeter/greeter.proto

# 指令2:paths为source_relative,pb文件最终在 proto/greeter 目录下
$ protoc --proto_path=. --go_out=paths=source_relative:. proto/greeter/greeter.proto

plugins参数带grpc时会生成一些跟gRPC相关的代码,实现gRPC通信。