grpb是网络通信协议,在网络通信时,你也会发送和接收数据。收发的数据使用protobuf进行编解码(当然它也可以使用其它的编解码方式,比如thrift、JSON,也可以自己造轮子,比如Go的gob)当然grpc作为一个rpc框架,数据的编解码只是其中一小部分,还有很多其它的工作需要处理,参见各种其它框架
下载
注意,不同的电脑系统安装包是不一样的:
配置环境变量
cd /usr/local/include/
mkdir proto
unzip -d /usr/local/include/proto protoc-21.6-linux-x86_64.zip
解压之后会出来两个文件夹子bin和include
然后配置环境变量
打开下面文件
sudo vim /etc/profile
在最后添加
export PATH=$PATH:/usr/local/include/proto/bin
export PATH=$PATH:/usr/local/include/proto/include
export PATH=$PATH:$GOROOT/bin #下面这两个是插件的路径,后面会用到,这里提前加好
export PATH=$PATH:$GOPATH/bin
再执行下面命令,然后重启。
source /etc/profile
重启之后,检查时候成功
protoc --version
libprotoc 3.21.6
安装protobuf-go插件
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
执行完毕之后,去GOPATH路径下查看,一定会有protoc-gen-go文件。
其环境变量已经在上边添加了,这里就不用再加了。
protobuf/
├── go.mod
├── go.sum
├── pbfiles
│ └── iphone.proto
└── proto_go
iphone.proto内容为:
syntax = "proto3"; //表示使用proto3
option go_package = "../proto_go;protos"; //指定protoc-gen-go生成的go包的名字和路径
message IPhoneInfo {
string name = 1;
int32 id = 2;
string email = 3;
enum phoneType{
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message phoneNumber{
string number = 1;
phoneType type = 2;
}
phoneNumber phones = 4;
}
message AddressBook {
repeated IPhoneInfo people = 1;
}
进入pbfiles文件夹,运行下面命令
protoc --go_out=../proto_go --go_opt=paths=source_relative iphone.proto
- protoc:为使用protoc编译器;
- –go_out=…/proto_go:表示要将生成的go文件输出到哪里;
- –go_opt=path=source_relative:表示出方式路径,是以相对路径表示的;
- iphone.proto:要进行编译的文件;
编译完毕之后,会在proto_go中出现iphone.pb.go文件。
编码演示首先下载go的protobuf库
go get github.com/golang/protobuf/proto
代码如下
package main
import (
"fmt"
"github.com/golang/protobuf/proto"
protos "protobuf/proto_go"
)
func main() {
p1 := &protos.IPhoneInfoPhoneNumber{
Number: "18131371661",
Type: 1,
}
s1 := &protos.IPhoneInfo{
Name: "ueueq",
Id: 10086,
Email: "cjs_svip@163.com",
Phones: p1,
}
p2 := &protos.IPhoneInfoPhoneNumber{
Number: "18131371662",
Type: 2,
}
s2 := &protos.IPhoneInfo{
Name: "queue",
Id: 86001,
Email: "cjs_svip@163.com",
Phones: p2,
}
book := &protos.AddressBook{People: []*protos.IPhoneInfo{s1, s2}}
m, err := proto.Marshal(book)
if err != nil {
panic(err)
}
fmt.Println("序列化后的数据: ", m)
decode := &protos.AddressBook{}
err = proto.Unmarshal(m, decode)
if err != nil {
panic(err)
}
fmt.Println("反序列化后的数据: ", decode)
}