前言

protobuf是二进制协议,传输效率极高,传输体积很小,在tcp/rpc里的使用很普及。

使用须知

和json不同,protobuf没有被放入官方的基本库里,也就不能直接​​proto.Marshal()​​.

使用protobuf前,需保证​​protoc.exe​​​与​​proto-gen-go.exe​​​在path里,命令行执行​​protoc --version​​ 有正确输出即可。

安装前,续保证​​git​​​正确安装,即输入​​git --version​​ 有正确输出。

使用golang操作protobuf,须正确安装go, 输入​​go version​​ 有正确输出

环境安装好了以后,需要知道如何书写proto文件。想要一概而精是不正常的,我们来通过需求来学习最佳。

安装protoc与proto-gen-go

protoc: https://github.com/golang/protobuf

proto-gen-go:https://github.com/golang/protobuf/tree/master/protoc-gen-go

  1. ​cd %GOPATH%​
  2. ​cd /src/github.com/golang​​不存在的文件夹时,则创建.
  3. ​git clone https://github.com/golang/protobuf.git protobuf​

如果git clone太慢了或者失败了:
在 https://github.com/golang/protobuf 里,选择Download zip, 并将protobuf-master改名为protobuf,并放置到​​​%GOPATH%/src/github.com/golang/protobuf​​即可

  1. 在​​https://github.com/protocolbuffers/protobuf/releases​​​中,windows版的,ctrl+f,查找​​win64​​​,可以快速定位到win版本的protoc,或者选择对应想要的版本的realse进行下载,解压,并将其中的protoc.exe放入​​%GOPATH%\bin​
  2. 在 ​​%GOPATH%\src\github.com\golang\protobuf\protoc-gen-go​​​路径下,执行​​go build -o protoc-gen-go.exe​
  3. 将4,5生成的protoc.exe与proto-gen-go.exe放入​​%GOPATH%\bin​​​并将​​%GOPATH%\bin​​添加到环境变量path里。

生成go model

cd /x/x/m.proto
protoc --go_out=. m.proto

小试牛刀

需要注意的是,protobuf要想得到对应的结构体,必须先从proto文件开始,并自动生成,而不是手动输入。
​​​mkdir pb​​​​cd pb​hello.proto

syntax = "proto3";
package pb;

message User {
int32 id = 1;
string username = 2;
}

在hello.proto路径下
​​​protoc --go_out=plugins=grpc:. hello.proto​

至此,go file已经自动生成了

小试牛刀,使用marshal和unmarshal

package main

import (
"fmt"
"github.com/golang/protobuf/proto"
"t/pb"
)

func main() {
buf , e:= proto.Marshal(&pb.User{
Id: 1,
Username: "csdn",
})

if e!=nil {
panic(e)
}

fmt.Println(buf)
var tmp pb.User
e = proto.Unmarshal(buf, &tmp)
if e!=nil {
panic(e)
}
fmt.Println(tmp)
}

几个常用的protoc命令:

​protoc --go_out=plugins=grpc:. example.proto​​​ 生成带有grpc服务端和测试端模块的代码
​​​protoc --go_out=plugins=micro:. hello_world.proto​​​ 生成micro生态的代码
·
​​​protoc --go_out=plugins=grpc:. -I=${GOPATH}/src -I=. xxx.proto​​​ 同时扫描了​​/.​​​和​​GOPATH/src​​ 两个路径,应对proto里存在import场景

常见错误

  1. unknow service xxxx
    可能是服务端和客户端的proto文件不一致,自动生成的代码存在误差,需要重新同步

注意

  1. proto文件里的package,必须统一。出错场景:服务端的proto文件共享给客户端,客户端复制一份一样的proto文件后,将内容package修改成了其它名字,将造成服务不识别。