Go语言操作protobuf协议
1.相关链接
Protocol Buffer Basics: Go(官方文档)
中文详细解释
2.使用步骤
1. 安装protobuf编译器
1.下载
我是用的是GO开发的,选择红色框的就行,右击复制下载地址,使用wget下载。
该版本的为免编译的,直接就能用。
2.配置环境变量
建议在/usr/loacl/include/下建立一个proto文件夹
cd /usr/local/include/
mkdir proto
然后解压到这个文件夹
unzip -d /usr/local/include/proto protoc-21.6-linux-x86_64.zip
解压之后会出来两个文件夹子bin和include
然后配置环境变量
打开下面文件
sudo vim /etc/profile
在最后添加
export PATH=$PATH:/usr/local/include/proto/bin
export PATH=$PATH:/usr/local/include/proto/include
export PATH=$PATH:$GOROOT/bin #下面这两个是插件的路径,后面会用到,这里提前加好
export PATH=$PATH:$GOPATH/bin
再执行下面命令,然后重启。
source /etc/profile
重启之后,检查时候成功
protoc --version
libprotoc 3.21.6
2. 安装protobuf-go插件
直接一条命令
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
执行完毕之后,去GOPATH路径下查看,一定会有protoc-gen-go文件。
其环境变量已经在上边添加了,这里就不用再加了。
3. 编写protobuf文件,并编译出go文件
syntax = "proto3"; //表示使用proto3
option go_package = "../proto_go;protos"; //指定protoc-gen-go生成的go包的名字和路径
message IPhoneInfo {
string name = 1;
int32 id = 2;
string email = 3;
enum phoneType{
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message phoneNumber{
string number = 1;
phoneType type = 2;
}
phoneNumber phones = 4;
}
message AddressBook {
repeated IPhoneInfo people = 1;
}
我的文件路径为:
protobuf/
├── go.mod
├── go.sum
├── pbfiles
│ └── iphone.proto
└── proto_go
进入pbfiles文件夹,运行下面命令
protoc --go_out=../proto_go --go_opt=paths=source_relative iphone.proto
protoc:为使用protoc编译器;
–go_out=…/proto_go:表示要将生成的go文件输出到哪里;
–go_opt=path=source_relative:表示出方式路径,是以相对路径表示的;
iphone.proto:要进行编译的文件;
编译完毕之后,会在proto_go中出现iphone.pb.go文件。
4. 编码演示
首先下载go的protobuf库
go get github.com/golang/protobuf/proto
代码如下
package main
import (
"fmt"
"github.com/golang/protobuf/proto"
protos "protobuf/proto_go"
)
func main() {
p1 := &protos.IPhoneInfoPhoneNumber{
Number: "18131371661",
Type: 1,
}
s1 := &protos.IPhoneInfo{
Name: "ueueq",
Id: 10086,
Email: "cjs_svip@163.com",
Phones: p1,
}
p2 := &protos.IPhoneInfoPhoneNumber{
Number: "18131371662",
Type: 2,
}
s2 := &protos.IPhoneInfo{
Name: "queue",
Id: 86001,
Email: "cjs_svip@163.com",
Phones: p2,
}
book := &protos.AddressBook{People: []*protos.IPhoneInfo{s1, s2}}
m, err := proto.Marshal(book)
if err != nil {
panic(err)
}
fmt.Println("序列化后的数据: ", m)
decode := &protos.AddressBook{}
err = proto.Unmarshal(m, decode)
if err != nil {
panic(err)
}
fmt.Println("反序列化后的数据: ", decode)
}