golang使用protobuf

簡介

http中常用的json協(xié)議一樣曹傀,protobuf也是用來傳輸數(shù)據(jù)的含鳞,但是它使用二進(jìn)制格式,傳輸效率更高泼橘。

安裝

  1. 下載protoc二進(jìn)制程序
    下載鏈接
    在windows上秘噪,選擇protoc-3.7.0-rc-2-win64.zip 進(jìn)行下載魁索。
    壓縮包中有兩個(gè)文件夾:
    壓縮包中文件夾.png

    bin目錄下的protoc.exe拷貝到GOPATH/bin目錄下融撞,將include/目錄下的google文件夾拷貝GOPATH/src目錄下(只有使用protobuf的一些內(nèi)置結(jié)構(gòu)才需要用到該文件夾內(nèi)的文件,這次并不會(huì)用到這個(gè)文件夾)粗蔚。
  2. 安裝protobuf的編譯器插件protoc-gen-go
    protoc程序會(huì)調(diào)用protoc-gen-go尝偎,將.proto文件生成golang代碼∨艨兀可以使用go get命令安裝:
go get -u -v github.com/golang/protobuf/protoc-gen-go

安裝成功后致扯,會(huì)在GOPATH/bin下生成protoc-gen-go.exe程序。

例子

demo為官網(wǎng)tutorial的簡化版本当辐。

在GOPATH/src/all-demo下抖僵,目錄結(jié)構(gòu)為:

protobuf-demo
    demo1
        addressbook
            addressbook.pb.go
            addressbook.proto
        main.go

編寫、編譯addressbook.proto文件

其中addressbook.proto文件為:

// [START declaration]
syntax = "proto3";
package addressbook;

// [END declaration]

// [START messages]
message Person {
  string name = 1;
  int32 id = 2;  // Unique ID number for this person.
  string email = 3;

  enum PhoneType {
    MOBILE = 0;
    HOME = 1;
    WORK = 2;
  }

  message PhoneNumber {
    string number = 1;
    PhoneType type = 2;
  }

  repeated PhoneNumber phones = 4;
}

// Our address book file is just one of these.
message AddressBook {
  repeated Person people = 1;
}
// [END messages]

其中:

  1. syntax設(shè)置語法類型缘揪,有proto2proto3兩種語法耍群。
  2. package addressbook可以設(shè)置生成的golang代碼的包名义桂。
  3. message對(duì)應(yīng)于golang中的struct,可以看到文件中一共定義了Person世吨,PhoneNumber澡刹,AddressBook3個(gè)message,其中PhoneNumberPerson的嵌套類型耘婚。
  4. message中有字段,可以是int陆赋,string沐祷,枚舉或者其他消息類型。
  5. repeated表示該字段可以不止一個(gè)攒岛,類似于golang中的slice赖临。

編譯

命令行進(jìn)入GOPATH/src/all-demo/protobuf-demo/demo1/addressbook,
執(zhí)行protoc --go_out=. addressbook.proto,會(huì)在該目錄下生成addressbook.pb.go文件灾锯。
其中 --go_out指定生成的golang文件的目錄兢榨。

addressbook.pb.go部分源碼如下:

// 可以看到包名為addressbook
package addressbook
// [START messages]
type Person struct {
    Name                 string                `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
    Id                   int32                 `protobuf:"varint,2,opt,name=id,proto3" json:"id,omitempty"`
    Email                string                `protobuf:"bytes,3,opt,name=email,proto3" json:"email,omitempty"`
    Phones               []*Person_PhoneNumber `protobuf:"bytes,4,rep,name=phones,proto3" json:"phones,omitempty"`
    XXX_NoUnkeyedLiteral struct{}              `json:"-"`
    XXX_unrecognized     []byte                `json:"-"`
    XXX_sizecache        int32                 `json:"-"`
}
type Person_PhoneNumber struct {
    Number               string           `protobuf:"bytes,1,opt,name=number,proto3" json:"number,omitempty"`
    Type                 Person_PhoneType `protobuf:"varint,2,opt,name=type,proto3,enum=addressbook.Person_PhoneType" json:"type,omitempty"`
    XXX_NoUnkeyedLiteral struct{}         `json:"-"`
    XXX_unrecognized     []byte           `json:"-"`
    XXX_sizecache        int32            `json:"-"`
}
// Our address book file is just one of these.
type AddressBook struct {
    People               []*Person `protobuf:"bytes,1,rep,name=people,proto3" json:"people,omitempty"`
    XXX_NoUnkeyedLiteral struct{}  `json:"-"`
    XXX_unrecognized     []byte    `json:"-"`
    XXX_sizecache        int32     `json:"-"`
}

編寫main.go

代碼主要測(cè)試proto.Marshalproto.UnMarshal的功能。先定義一個(gè)pb.AddressBook 結(jié)構(gòu)體顺饮,并將其初始化吵聪,用proto.Marshal將其序列化成二進(jìn)制數(shù)據(jù),寫入文件兼雄,再將其從文件中讀取吟逝,使用proto.UnMarshal反序列化成結(jié)構(gòu)體。
代碼如下:

package main

import (
    "fmt"
    pb "all-demo/protobuf-demo/demo1/addressbook"
    "io/ioutil"
    "log"
    "github.com/golang/protobuf/proto"
)

func main() {
    // 自定義AddressBook內(nèi)容
    book := &pb.AddressBook{
        People: []*pb.Person {
            &pb.Person{
                Id: 1,
                Name: "zyq",
                Email: "77@qq.com",
                Phones: []*pb.Person_PhoneNumber{
                    &pb.Person_PhoneNumber {
                        Number: "11111",
                        Type: pb.Person_MOBILE,
                    },
                    &pb.Person_PhoneNumber {
                        Number: "22222",
                        Type: pb.Person_HOME,
                    },
                },
            },
        },
    }
    fmt.Println("book : ",book)

    fname := "address.dat"
    // 將book進(jìn)行序列化
    out, err := proto.Marshal(book)
    if err != nil {
        log.Fatalln("Failed to encode address book:", err)
    }
    // 將序列化的內(nèi)容寫入文件
    if err := ioutil.WriteFile(fname, out, 0644); err != nil {
        log.Fatalln("Failed to write address book:", err)
    }

    // 讀取寫入的二進(jìn)制數(shù)據(jù)
    in, err := ioutil.ReadFile(fname)
    if err != nil {
        log.Fatalln("Error reading file:", err)
    }

    // 定義一個(gè)空的結(jié)構(gòu)體
    book2 := &pb.AddressBook{}
    // 將從文件中讀取的二進(jìn)制進(jìn)行反序列化
    if err := proto.Unmarshal(in, book2); err != nil {
        log.Fatalln("Failed to parse address book:", err)
    }

    fmt.Println("book2: ",book2)
}

執(zhí)行結(jié)果為:

book :  people:<name:"zyq" id:1 email:"77@qq.com" phones:<number:"11111" > phones:<number:"22222" type:HOME > > 
book2:  people:<name:"zyq" id:1 email:"77@qq.com" phones:<number:"11111" > phones:<number:"22222" type:HOME > > 

問題:

  • 還有很多語法不了解赦肋。
  • proto.UnMarshal函數(shù)的聲明為func Unmarshal(buf []byte, pb Message) error块攒,該函數(shù)的第二個(gè)參數(shù)為proto.Message接口,在網(wǎng)絡(luò)傳輸中佃乘,服務(wù)端怎么知道客戶端發(fā)過來的到底是哪一種message囱井。

參考

  1. https://developers.google.com/protocol-buffers/docs/gotutorial
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市趣避,隨后出現(xiàn)的幾起案子庞呕,更是在濱河造成了極大的恐慌,老刑警劉巖鹅巍,帶你破解...
    沈念sama閱讀 218,682評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件千扶,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡骆捧,警方通過查閱死者的電腦和手機(jī)澎羞,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來敛苇,“玉大人妆绞,你說我怎么就攤上這事顺呕。” “怎么了括饶?”我有些...
    開封第一講書人閱讀 165,083評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵株茶,是天一觀的道長。 經(jīng)常有香客問我图焰,道長启盛,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,763評(píng)論 1 295
  • 正文 為了忘掉前任技羔,我火速辦了婚禮僵闯,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘藤滥。我一直安慰自己鳖粟,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評(píng)論 6 392
  • 文/花漫 我一把揭開白布拙绊。 她就那樣靜靜地躺著向图,像睡著了一般。 火紅的嫁衣襯著肌膚如雪标沪。 梳的紋絲不亂的頭發(fā)上榄攀,一...
    開封第一講書人閱讀 51,624評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音谨娜,去河邊找鬼航攒。 笑死,一個(gè)胖子當(dāng)著我的面吹牛趴梢,可吹牛的內(nèi)容都是我干的漠畜。 我是一名探鬼主播,決...
    沈念sama閱讀 40,358評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼坞靶,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼憔狞!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起彰阴,我...
    開封第一講書人閱讀 39,261評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤瘾敢,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后尿这,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體簇抵,經(jīng)...
    沈念sama閱讀 45,722評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年射众,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了碟摆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,030評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡叨橱,死狀恐怖典蜕,靈堂內(nèi)的尸體忽然破棺而出断盛,到底是詐尸還是另有隱情,我是刑警寧澤愉舔,帶...
    沈念sama閱讀 35,737評(píng)論 5 346
  • 正文 年R本政府宣布钢猛,位于F島的核電站,受9級(jí)特大地震影響轩缤,放射性物質(zhì)發(fā)生泄漏命迈。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評(píng)論 3 330
  • 文/蒙蒙 一典奉、第九天 我趴在偏房一處隱蔽的房頂上張望躺翻。 院中可真熱鬧,春花似錦卫玖、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至迂尝,卻和暖如春脱茉,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背垄开。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評(píng)論 1 270
  • 我被黑心中介騙來泰國打工琴许, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人溉躲。 一個(gè)月前我還...
    沈念sama閱讀 48,237評(píng)論 3 371
  • 正文 我出身青樓榜田,卻偏偏與公主長得像,于是被迫代替她去往敵國和親锻梳。 傳聞我的和親對(duì)象是個(gè)殘疾皇子箭券,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • json與protobuf做數(shù)據(jù)傳輸對(duì)比:json用起來的確很方便。但相對(duì)于protobuf數(shù)據(jù)量更大些疑枯。做一個(gè)移...
    Gospel元嘉閱讀 4,839評(píng)論 0 4
  • 一辩块、安裝protobuf 1.去github下載protobuf,網(wǎng)址是https://github.com/go...
    大嘯閱讀 2,194評(píng)論 0 0
  • 1荆永、安裝 protoc 在該鏈接下下載protoc-3.3.0-win32.zip的包 將文件解壓到某一文件夾 將...
    莫夏_b560閱讀 3,721評(píng)論 0 0
  • Protobuf 介紹 序列化庫在網(wǎng)絡(luò)傳輸废亭,RPC,數(shù)據(jù)庫訪問等環(huán)境中經(jīng)常用到具钥,它的性能的好壞直接影響著整個(gè)產(chǎn)品的...
    Aedan閱讀 3,926評(píng)論 0 0
  • 近幾年氓拼,甜品行業(yè)的迅速興起逐步發(fā)展成為了我國餐飲行業(yè)的一支重要力量你画,在為眾多消費(fèi)者提供美食的同時(shí)也成為投資人創(chuàng)富的...
    進(jìn)月少女的禮儀閱讀 225評(píng)論 0 0