下载地址

https://github.com/protocolbuffers/protobuf/releases

找到对应系统版本下载,如window(mac 可以用brew包管理)下载之后解压,在环境变量中path增加protobuf的解压之后的路径D:\Program Files\protoc-24.2-win64\bin

查看是否安装成功

1
2
终端输入命令:protoc  --version
终端返回:libprotoc 3.11.4

利用protoc生成文件

  1. 下载go插件(这里是新版操作)
1
2
3
go get google.golang.org/grpc
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
  1. 创建 .proto 后缀的文件名
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
// 版本号,不声明默认proto2版本
syntax = "proto3";

option go_package = "./;proto"; // 对应:生成位置;包名

// 指定包名
//package proto;

// LoginRequest 登录请求
message LoginRequest {
string username = 1; // 登录用户名,这里的1是个编号,不是值
string password = 2; // 登录密码
}

// LoginResponse 登录响应结构体
message LoginResponse {
int32 id = 1;
// repeated修饰符是可变数组,go转切片
repeated string hobby = 2;
}

// service定义方法
service LoginService {
rpc GetLogin (LoginRequest) returns (LoginResponse) {}
}
  1. 执行命令生成对应文件
1
2
3
4
5
(新版命令)
protoc --go_out=. login.proto => 对应生成 login.pd.go 文件
protoc --go-grpc_out=. login.proto => 对应生成 login_grpc.pd.go 文件
(旧版命令)
protoc -I . login.proto --go_out=plugins=grpc:.

proto文件同步的坑

注意文件定义的参数编号需要一致,否则取值之后的顺序不同

proto文件中import另一个proto文件

引入自定义proto文件

文件connect.proto

1
2
3
4
5
6
7
syntax = "proto3";
import "base.proto"; //引入base.proto文件
option go_package = "./;proto";

service Greeter {
rpc Ping (Ping) returns (Pong) {};
}

文件base.proto

1
2
3
4
5
6
7
8
9
10
syntax = "proto3";
option go_package = "./;proto";
message Ping {

}

message Pong {
string id = 1;
}

引入protobuf内置的proto文件

1
2
3
4
5
6
7
8
9
10
11
syntax = "proto3";
import "google/protobuf/empty.proto"; //引入内置的文件
option go_package = "./;proto";

service Greeter {
rpc Ping (google.protobuf.Empty) returns (Pong) {};
}

message Pong {
string id = 1;
}

嵌套的message对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
syntax = "proto3";
option go_package = "./;proto";

service Greeter {
rpc Ping (Ping) returns (Pong) {};
}

message Ping {
string id = 1;
}

message Pong {
string id = 1;

message Result { // 这里使用内嵌方式,外嵌也可以,但是参数的编号可能会有冲突的情况
string msg = 1;
}
repeated Result data = 2;
}