一、protobuf构建
protobuf是一种轻量级、高效、平台无关、语言无关、扩展性强的数据序列化和反序列化协议。在protobuf中,开发者可以通过定义消息格式,自动生成数据访问API,从而达到数据传输和存储的目的。
protobufgo是Golang社区提供的一种开源工具,旨在为Golang开发者提供高效、灵活、跨语言的protobuf序列化和反序列化功能。使用protobufgo,我们可以方便地通过protobuf定义文件,生成Golang访问API,并且可以与其他语言的protobuf代码进行互操作。
我们可以通过以下步骤来构建protobufgo:
// 安装protobuf工具 $ go get github.com/golang/protobuf/proto // 安装protobufgogo插件 $ go get github.com/gogo/protobuf/proto $ go get github.com/gogo/protobuf/protoc-gen-gogo
二、protobuf工具
protobufgo提供了许多有用的工具,可以帮助我们更轻松地开发和维护代码。以下是一些常用的工具:
1. protoc
protoc是protobuf官方提供的编译器,负责将protobuf定义文件编译成不同语言的访问API。protobufgo通过gogo/protobuf插件对protoc进行了扩展,提供了更多的选项和功能,例如生成更快的序列化和反序列化方法、支持不同语言之间的互操作等。
2. protoc-gen-go
protoc-gen-go是protobuf官方提供的Golang插件,用于将protobuf定义文件编译成Golang访问API。protobufgo提供了gogo/protobuf插件,可以生成更高效的序列化和反序列化方法,也可以支持更多的选项和功能,例如生成google.golang.org/genproto包下的Golang protobuf代码。
3. protoc-gen-gofast
protoc-gen-gofast是protobufgo提供的一个更快的Golang插件,它基于gogo/protobuf插件进行了优化,生成的代码速度更快。
4. protoc-gen-grpc-gateway
protoc-gen-grpc-gateway是一个开源的grpc转换代理,可以将标准的grpc服务转换成RESTful的API接口,支持多种编程语言,包括Golang。
三、protobuf公参
protobuf定义文件定义了消息的结构和字段信息,类似于Golang中的struct,包括以下4个要素:
1. package
指定生成的代码所在的Golang代码包。
2. import
导入其他protobuf定义文件。
3. message
定义消息结构和字段信息。
4. service
定义服务器和客户端之间的远程调用接口。
以下是一个简单的protobuf定义文件的示例:
syntax = "proto3"; package example; import "google/protobuf/timestamp.proto"; message Person { string name = 1; int32 age = 2; repeated string email = 3; google.protobuf.Timestamp created_time = 4; } service PersonService { rpc GetPerson (PersonRequest) returns (PersonResponse); } message PersonRequest { string name = 1; } message PersonResponse { Person person = 1; }
四、protobuf构建与移植
protobufgo提供了多种选项和调用方式,以满足不同平台和应用场景的需要。总体而言,protobufgo可以分为以下3个部分进行构建和移植:
1. protoc编译器
protoc编译器是protobufgo的核心,可以将protobuf定义文件编译成不同语言的访问API。protobufgo通过gogo/protobuf插件对protoc进行了扩展,提供了更多的选项和功能,例如生成更快的序列化和反序列化方法、支持不同语言之间的互操作等。以下是一些常用的命令:
// 编译proto文件 $ protoc --proto_path=$GOPATH/src:. --gogo_out=. file.proto // 支持生成其他语言的代码,例如Java: $ protoc --proto_path=$GOPATH/src:. --java_out=. file.proto
2. gogo/protobuf插件
gogo/protobuf插件是protobufgo提供的一种高效、灵活、跨语言的protobuf序列化和反序列化库。在Golang应用程序中使用protobufgo,需要先将protobuf定义文件编译成Golang访问API,然后将生成的代码导入到应用程序中。以下是一些常用的命令:
// 安装插件 $ go get github.com/gogo/protobuf/proto $ go get github.com/gogo/protobuf/protoc-gen-gogo // 编译proto文件 $ protoc --proto_path=$GOPATH/src:. --gogo_out=. file.proto
3. 应用程序
在应用程序中使用protobufgo,需要导入protobuf生成的Golang代码,并定义和使用消息结构体。
import "example/file.pb.go" func main() { person := &example.Person{ Name: "Tom", Age: 28, Email: []string{"tom@example.com", "tom@gmail.com"}, CreatedTime: ×tamp.Timestamp{ Seconds: time.Now().Unix(), }, } data, _ := proto.Marshal(person) newPerson := &example.Person{} _ = proto.Unmarshal(data, newPerson) }
五、protobuf共享内存
protobufgo支持将消息数组序列化到共享内存中,以实现进程之间的数据传递和共享。以下是一些常用的命令:
// 获取消息占用的共享内存大小 size := proto.Size(msg) // 分配共享内存 shmID, err := ipc.ShmGet(1, size, ipc.IPC_CREAT|ipc.IPC_EXCL|0666) // 将消息序列化到共享内存 msgBytes, err := proto.Marshal(msg) shmbuf, err := ipc.Shmat(shmID, uintptr(0), 0) copy((*((*[1 << 30]byte)(unsafe.Pointer(shmbuf))))[:size], msgBytes) ipc.Shmdt(shmbuf) // 从共享内存中反序列化消息 shmbuf, err = ipc.Shmat(shmID, uintptr(0), 0) unmarshMsg := &T{} _ = proto.Unmarshal(shmbuf[:size], unmarshMsg) ipc.Shmdt(shmbuf)
六、protobuf工具转json
protobufgo支持将消息序列化为JSON字符串,以方便在HTTP API中传输和返回。以下是一些常用的命令:
// 将消息序列化为JSON字符串 buf, err := protojson.Marshal(msg) // 将JSON字符串反序列化为消息 newMsg := &T{} _ = protojson.Unmarshal(buf, newMsg)
上述代码片段中的T代表消息结构体。
七、总结
protobufgo是一种高效、灵活、跨语言的数据序列化和反序列化协议,提供了强大的命令工具和访问API,可以帮助我们更轻松地开发和维护代码。