1.下载二进制包
wget https://github.com/protocolbuffers/protobuf/releases/download/v3.17.3/protoc-3.17.3-linux-x86_64.zip
2.解压设置环境变量
unzip protoc-3.17.3-linux-x86_64.zip -d protoc
// shell 环境变量
vim /etc/profile
export PROTOC=~/protoc
export PATH=$PATH:$PROTOC/bin
source /etc/profile
//fish 环境变量
vim ~/.config/fish/config.fish
set -x PROTOC /home/wzl/protoc
set -x PATH $PROTOC/bin $PATH
sudo vim /etc/fish/config.fish
source /etc/fish/config.fish
3.测试命令提示
git clone https://github.com/golang/protobuf.git
mv protobuf $GOMODCACHE/github.com/golang/
cd $GOMODCACHE/github.com/golang/protobuf/protoc-gen-go
go build
sudo cp protoc-gen-go /bin
//有自动提示安装成功
1.定义消息体
//默认是proto2
syntax="proto3";
//指定所在包名
package pb;
//定义消息体
message Person {
string name = 1;//字段编号,可不从1开始,但不能重复
int32 age = 2;
}
2.消息体嵌套
syntax="proto3";
package pb;
message Person {
string name = 1;
int32 age = 2;
PhoneNumber p = 3; //消息体可嵌套
}
message PhoneNumber {
string number = 1;
int64 type = 2;
}
3.字段编号
1)每个字段唯一编号
2)范围:1 - 536870911,其中19000~19999是协议缓冲区保留数
repeadted关键字类似与go中的切片,编译之后对应的也是go的切片:
syntax="proto3";
package pb;
message Person {
string name = 1;
int32 age = 2;
message PhoneNumber {
string number = 1;
int64 type = 2;
}
repeated PhoneNumber phone = 3; //数组
}
syntax="proto3";
package pb;
//定义枚举类型
enum Week {
Monday = 0; //枚举值,必须从0开始,与写入编号无关
Turesday =1;
}
message Person {
string name = 1;
int32 age = 2;
//枚举
Week w = 5;
}
syntax="proto3";
package pb;
message Person {
string name = 1;
int32 age = 2;
//联合体
oneof data {
string teacher = 3; //写入编号不能重复
string class = 4;
}
}
go编译命令
protoc --go_out=./ *.proto ---> xxx.pb.go
c++编译命令
protoc --cpp_out=./ *.proto ---> xxx.pb.cc,xxx.pb.h
protoc-gen-go: unable to determine Go import path for "test.proto"
Please specify either:
? a "go_package" option in the .proto source file, or
? a "M" argument on the command line.
- 修改错误
文件中添加 option go_package = "path/packageName";
// 或 "../pb;pb" 路径;包名
syntax="proto3";
package pb;
option go_package = "./pb"; //生成包路径
message Person {
string name = 1;
int32 age = 2;
PhoneNumber p = 3; //消息体可嵌套
}
message PhoneNumber {
string number = 1;
int64 type = 2;
}
- 语法
service 服务名 {
rpc 函数名(参数:消息体) returns (返回值:消息体)
}
例
message People {
string name = 1;
}
message Man {
int32 age = 2;
}
service hello {
rpc HelloPeple(People) returns (Man);
}
protoc --go_out=plugins=grpc:./ *.proto
package main
import (
"ImTransfer/pb"
"fmt"
"google.golang.org/protobuf/proto"
)
func main() {
req := pb.PhoneNumber{
Number: "123",
Type: 11,
}
rsp, _ := proto.Marshal(&req)
fmt.Println(string(rsp))
}
import (
"ImTransfer/pb"
"fmt"
"google.golang.org/protobuf/proto"
)
func main() {
req := pb.PhoneNumber{
Number: "123",
Type: 11,
}
rsp, _ := proto.Marshal(&req)
fmt.Println(string(rsp))
//反序列化
newReq := new(pb.PhoneNumber)
_ = proto.Unmarshal(rsp, newReq)
fmt.Println(newReq)
}
原文:https://www.cnblogs.com/wangzhilei-src/p/15253140.html