安装protobuf编译器

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文件
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)
}