protocol buffers
简介
数据传输方式有:json和xml两种格式,其中json更多一些。现在又多了一种数据传输方式,就是google开发的Protocol Buffers
Protocol Buffers一个字“快”。一条消息数据,用protobuf序列化后的大小是json的10分之一,是xml格式的20分之一,但是性能却是它们的5~100倍
下载protocol buffers编译器
https://github.com/protocolbuffers/protobuf
点击右侧releases在下面找assets下面对应操作系统的压缩包
解压放到磁盘
C:\Program Files\protoc-3.20.0-win64
把对应位置bin配置到系统环境变量
可在任意位置输入protoc
编写第一个protobuf文件,编译成go文件
为vscode安装vscode-proto3插件
vscode-proto3
创建一个protobuf文件
创建1.proto文件
syntax = "proto3";
option go_package="./;hello";
package hello;
message Person{
string name = 1;
int32 age = 2;
string email = 3;
}
option go_package = “path;name”;
path 表示生成的go文件的存放地址,会自动生成目录的。 name 表示生成的go文件所属的包名
安装go protocol buffers 插件
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
编译生成go文件
所有proto文件放在proto文件夹,所有go文件放在go文件夹
protoc --go_out=./go ./proto/*
protocol buffers
定义消息类型
syntax = "proto3";
message SearchRequest{
string query = 1;
int32 page_number = 2;
int32 result_per_page = 3;
}
文件第一行指定使用的是proto3语法,这必须是文件的第一个非空、非注释行
SearchRequest消息定义了三个字段
保留字段
message Foo {
reserved 2, 15, 9 to 11;
reserved "foo", "bar";
}
枚举类型
syntax = "proto3";
message SearchRequest{
string query = 1;
int32 page_number = 2;
int32 result_per_page = 3;
enum Corpus {
PHP = 0;
GO = 1;
JAVA = 2;
PYTHON = 3;
}
Corpus corpus = 4;
}
Corpus枚举的第一个常量映射到0,每个枚举定义都必须包含一个映射到0的常量作为其第一个元素
protobuf序列化和反序列化
创建user的proto
syntax = "proto3";
option go_package="./;user";
package user;
message Article{
int32 aid = 1;
string title = 2;
int32 views = 3;
}
生成user.pb.go文件
protoc --go_out=./user ./user/*
编写测试代码
func main() {
article := &user.Article{
Aid: 1,
Title: "protobuf for go",
Views: 10,
}
// 序列化成二进制
b, _ := proto.Marshal(article)
fmt.Printf("b: %v\n", b)
otherArticle := &user.Article{}
proto.Unmarshal(b, otherArticle)
fmt.Printf("otherArticle.GetAid(): %v\n", otherArticle.GetAid())
fmt.Printf("otherArticle.GetTitle(): %v\n", otherArticle.GetTitle())
fmt.Printf("otherArticle.GetViews(): %v\n", otherArticle.GetViews())
}
运行结果
PS D:\go\test\grpctest> go run .\test.go
b: [8 1 18 15 112 114 111 116 111 98 117 102 32 102 111 114 32 103 111 24 10]
otherArticle.GetAid(): 1
otherArticle.GetTitle(): protobuf for go
otherArticle.GetViews(): 10
PS D:\go\test\grpctest>
protobuf和json相互转换
下载安装protojson
go get google.golang.org/protobuf/encoding/protojson
编写测试go代码
func test1() {
article := &user.Article{
Aid: 1,
Title: "protobuf for go",
Views: 10,
}
jsonString := protojson.Format(article.ProtoReflect().Interface())
fmt.Printf("jsonString: %v\n", jsonString)
m := article.ProtoReflect().Interface()
protojson.Unmarshal([]byte(jsonString), m)
fmt.Printf("m: %v\n", m)
}
运行结果
PS D:\go\test\grpctest> go run .\test.go
jsonString: {
"aid": 1,
"title": "protobuf for go",
"views": 10
}
m: aid:1 title:"protobuf for go" views:10
PS D:\go\test\grpctest>