This is a creation in Article, where the information may have evolved or changed.
Why to use Protobuf
In recent projects, data transfer has been done using JSON. JSON is really handy. But the amount of data is larger relative to the protobuf. It is necessary to do a mobile application to save the user a bit of traffic. You can also learn about the use of protobuf
Protobuf higher performance and more specification than JSON
Fast codec speed and small data volume
Use the uniform specification, no longer worry about the case of different casing causes the problem of the egg pain such as parsing failure
But also lost some of the convenience
Installation
Using Protobuf in Go, there are two optional package goprotobuf (go official) and gogoprotobuf.
GOGOPROTOBUF is fully compatible with Google Protobuf, which generates code quality and codec performance higher than GOPROTOBUF.
Installing PROTOC
First go to Https://github.com/google/pro ... Download Protobuf compiler protoc,windows can be directly down to the EXE file (Linux will need to compile), and finally copy the downloaded executable file to $gopath Bin directory ($GOPATH/bin directory is best added to the system environment variable)
Installing the PROTOBUF library file
go get github.com/golang/protobuf/proto
Goprotobuf
Installing plugins
go get github.com/golang/protobuf/protoc-gen-go
Generate Go File
protoc --go_out=. *.proto
Gogoprotobuf
Installing plugins
Gogoprotobuf has two plugins to use
Protoc-gen-gogo: Similar to protoc-gen-go generated files, performance is almost the same (a little bit faster)
Protoc-gen-gofast: Generated files are more complex and have higher performance (5-7 faster)
//gogogo get github.com/gogo/protobuf/protoc-gen-gogo//gofastgo get github.com/gogo/protobuf/protoc-gen-gofast
Installing the GOGOPROTOBUF library file
go get github.com/gogo/protobuf/protogo get github.com/gogo/protobuf/gogoproto //这个不装也没关系
Generate Go File
//gogoprotoc --gogo_out=. *.proto//gofastprotoc --gofast_out=. *.proto
Performance testing
It's just a simple test with go.
//goprotobuf"编码":447ns/op"解码":422ns/op//gogoprotobuf-go"编码":433ns/op"解码":427ns/op//gogoprotobuf-fast"编码":112ns/op"解码":112ns/op
Simple use of Go_protobuf
Test.proto
syntax = "proto3"; //指定版本,必须要写(proto3、proto2) package proto;enum FOO { X = 0; };//message是固定的。UserInfo是类名,可以随意指定,符合规范即可message UserInfo{ string message = 1; //消息 int32 length = 2; //消息大小 int32 cnt = 3; //消息计数}
Client_protobuf.go
Package Mainimport ("Bufio" "FMT" "NET" "OS" Stproto "Proto" "Time"//protobuf codec library, the following two libraries are mutually compatible and can use their Any one "Github.com/golang/protobuf/proto"//"Github.com/gogo/protobuf/proto") func main () {StrIP: = "localhost:660 0 "Var conn net. Conn var err error//connection server for Conn, err = net. Dial ("TCP", StrIP); Err! = Nil; Conn, err = net. Dial ("TCP", StrIP) {fmt. PRINTLN ("Connect", StrIP, "fail") time. Sleep (time. Second) fmt. Println ("Reconnect ...")} FMT. PRINTLN ("Connect", StrIP, "success") defer Conn. Close ()//Send message cnt: = 0 Sender: = Bufio. Newscanner (OS. Stdin) for sender. Scan () {cnt++ stsend: = &stproto.userinfo{message:sender. Text (), Length: *proto. Int (len (sender). Text ())), Cnt: *proto. Int (CNT),}//PROTOBUF encoded PData, err: = Proto. Marshal (stsend) if err! = Nil {panic (ERR)}//Send Conn. Write (PData) If sender. Text () = = "Stop" {return}}}
Server_protobuf.go
Package Mainimport ("FMT" "NET" "OS" Stproto "Proto"//protobuf codec library, the following two libraries are mutually compatible, you can use any one of them "github.com/ Golang/protobuf/proto "//" Github.com/gogo/protobuf/proto ") func main () {//Listener listener, ERR: = Net. Listen ("TCP", "localhost:6600") if err! = Nil {panic (err)} for {conn, err: = Listener. Accept () if err! = Nil {panic (err)} FMT. PRINTLN ("New Connect", Conn. REMOTEADDR ()) go Readmessage (conn)}}//Receive message func readmessage (conn net. Conn) {defer Conn. Close () Buf: = Make ([]byte, 4096, 4096) for {//Read message cnt, ERR: = conn. Read (BUF) if err! = Nil {panic (err)} streceive: = &stproto.userinfo{} pData: = buf[:cnt]//protobuf Decodes err = Proto. Unmarshal (PData, streceive) if err! = Nil {panic (err)} FMT. PRINTLN ("Receive", Conn. Remoteaddr (), streceive) if streceive.message = = "Stop" {OS.exit (1)}}