Protobuf 介紹
Protocol Buffers(又名 protobuf)是 Google 的語言中立、平臺中立、可擴充套件的結構化資料序列化機制。
https://github.com/protocolbuffers/protobuf
簡而言之,Protobuf 是 Google 開源的一款用於處理前後端資料互動格式的工具。通常來講前後端使用的程式語言是不同的,使用 Protobuf無需多慮,前後端只管約定通訊協議,之後就可以使用 pb 工具生成程式碼。
ProtoBuf 使用實戰
下載Protobuf
直接上Github 下載最新發行版,注意選擇自己電腦的平臺。
筆者使用的環境是 Ubuntu 20.10,也就是linux,下面是下載連結
wget https://github.com/protocolbuffers/protobuf/releases/download/v3.17.3/protoc-3.17.3-linux-x86_64.zip
安裝Protobuf
首先執行上條命令下載Protobuf,新建一個資料夾作為解壓目錄
mkdir protoc
unzip protoc-3.17.3-linux-x86_64.zip -d ./protoc
配置環境變數
這裡的路徑需要根據自身情況進行修改
vim ~/.bashrc
export PATH="$PATH:/[替換成protoc所處的路徑]/protoc/bin"
source ~./bashrc
使用Protobuf
這裡使用Golang 進行演示
- 使用golang還需要額外安裝一些外掛,這裡貼出外掛連結,也可以直接使用下面命令進行下載
外掛連結: https://github.com/grpc-ecosystem/grpc-gateway
一鍵式安裝:go get\
github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway \
github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2 \
google.golang.org/protobuf/cmd/protoc-gen-go \
google.golang.org/grpc/cmd/protoc-gen-go-grpc
這時候檢查你的go/bin 目錄下就會多出以上幾個程式
如果不知道自己go/bin 路徑,可以通過 go env 檢視
$ go env
GO111MODULE="on"
GOARCH="amd64"
GOBIN="/xxx/go/bin"
定義訊息的格式
- syntax 指定proto 版本
- package 指定包名
- proto 生成的路徑
- 其餘可以檢視下面程式碼進行參考
建立 proto 檔案hello.proto 檔案內容如下:
syntax = "proto3";
package hello;
option go_package = "hello/proto/gen/go;hello";
message ProtoInfo {
string version = 1;
}
enum ProtoEnum {
HELLO_ONE = 0;
HELLO_TWO = 1;
}
message Hello {
string first = 1;
string second = 2;
int64 number_int64 = 3;
ProtoInfo proto_info = 4;//複合型別
repeated int32 array_int32 = 5;//陣列
ProtoEnum proto_enum = 6;
}
生成pb 檔案
protoc -I=. --go_out=paths=source_relative:gen/go hello.proto
- -I 指定當前路徑,--go_out 指定pb 檔案的生成路徑,具體可以參考:https://developers.google.com/protocol-buffers/docs/reference/go-generated
protobuf demo
執行生成命令後會生成pb 檔案,接下來看一下在專案中如何使用吧
package main
import (
"encoding/json"
"fmt"
hello "hello/proto/gen/go"
"google.golang.org/protobuf/proto"
)
func main() {
helloProto := hello.Hello{
First: "first",
Second: "second",
NumberInt64: 111,
ProtoInfo: &hello.ProtoInfo{
Version: "3",
},
ArrayInt32: []int32{1, 2, 3, 4, 5, 6},
ProtoEnum: hello.ProtoEnum_HELLO_TWO,
}
fmt.Printf("hello:%+v\n", &helloProto)
//轉成二進位制流
b, err := proto.Marshal(&helloProto)
if err != nil {
panic(err)
}
fmt.Printf("%X\n", b)
//從二進位制流轉成結構體
var hello2 hello.Hello
err = proto.Unmarshal(b, &hello2)
if err != nil {
panic(err)
}
fmt.Printf("hello2:%+v\n", &hello2)
//轉成json
jsonByte, err := json.Marshal(&hello2)
if err != nil {
panic(err)
}
fmt.Printf("string(jsonByte):%+v\n", string(jsonByte))
}
可以看到生成的pb 檔案不僅支援二進位制傳輸,同時也支援json 格式
執行demo得到如下結果:
hello:first:"first" second:"second" number_int64:111 proto_info:{version:"3"} array_int32:1 array_int32:2 array_int32:3 array_int32:4 array_int32:5 array_int32:6 proto_enum:HELLO_TWO
0A05666972737412067365636F6E64186F22030A01332A060102030405063001
hello2:first:"first" second:"second" number_int64:111 proto_info:{version:"3"} array_int32:1 array_int32:2 array_int32:3 array_int32:4 array_int32:5 array_int32:6 proto_enum:HELLO_TWO
string(jsonByte):{"first":"first","second":"second","number_int64":111,"proto_info":{"version":"3"},"array_int32":[1,2,3,4,5,6],"proto_enum":1}