protobuf初探笔记 - golang

认识protobuf

官网:https://developers.google.com/protocol-buffers

protobuf是google 的一种二进制数据交换的格式,类似于 json, xml等也是一种数据格式,是一个语言无关、平台无关的数据序列化工具。简单来说,如果客户端和服务端使用的是不同的语言,那么在服务端定义一个数据结构,通过protobuf转化为字节流,再传送到客户端解码,就可以得到对应的数据结构。

在一些场景下,数据需要在不同的平台,不同的程序中进行传输和使用,例如某个消息是用Java程序编写的的,而另一个程序是用golang写的,当前者产生一个消息数据时,需要在不同的语言编写的不同的程序中进行操作,我们常用的就有json和xml,但
protobuf序列化和反序列的性能都是比较高的,protobuf序列化后的数据体积更小”。

安装 protobuf 编译插件

默认已经安装go环境和brew

  1. protoc的安装:
    命令行执行:
brew install protobuf@3.7

安装完成之后执行:protoc --version 查看是否安装成功以及版本号

protoc --version

如下图显示内容,即为安装成功。
在这里插入图片描述

  1. protoc-gen-go插件的安装(将protobuf的的代码转换成go语言代码的一个插件):

命令行执行

go get github.com/golang/protobuf/protoc-gen-go@v1.3.2
  1. protoc-gen-micro插件的安装:

Go Micro默认使用protobuf作为通信协议的定义,故需要安装protoc-gen-micro来生成服务的接口代码,这样省去了很多重复的编码工作,同时也保证了代码的准确性。protoc-gen-micro依赖于protoc和protoc-gen-go

命令行执行

go get github.com/micro/protoc-gen-micro@v1.0.0

一个简单的例子-protobuf的使用

目录结构:

在这里插入图片描述

定义.proto文件

//.proto文件的第一行(syntax = "proto3";)指定了使用proto3语法。如果省略protocol buffer编译器默认使用proto2语法。他必须是文件中非空非注释行的第一行
syntax = "proto3”;
package proto;

import "google/protobuf/timestamp.proto";
import "google/protobuf/duration.proto";

//message是protobuf语法中的一个关键字,相当于golang编程语言中的结构体struct,相当于C++中的类。

message SendMessage {
 MessageMeta meta = 1;
 string Body = 2;
}

message MessageMeta {
 google.protobuf.Duration ttr = 1;
 google.protobuf.Timestamp timestamp = 2;
 string routingKey = 3;
 map<string, string> header = 4;
}

编译

进入到main.go所在目录下,打开Terminal执行命令:

protoc -I=proto --go_out=./proto message.proto

将会生成 message.pb.go 文件。message.pb.go文件会自动放入proto文件夹(对应上面package)中

在golang代码中使用protobuf中定义的内容

package main
import (
	"fmt"
	stProto "./examples/proto"
	"github.com/golang/protobuf/proto"
	"github.com/micro/go-micro/broker"
	"github.com/sirupsen/logrus"
	}
	
func main() {
.........初始化
	m := &stProto.SendMessage{
		Meta: &stProto.MessageMeta{
			Ttr:        ptypes.DurationProto(10 * time.Minute),
			Timestamp:  ptypes.TimestampNow(),
			RoutingKey: "micro.email.send",
			Header:     map[string]string{},
		},
		Body:   *proto.String("test send message by protobuf"),
	}
	encoded, err := proto.Marshal(m)
	if err != nil {
		fmt.Printf("Encode to protobuf data error: %v", err)
	}
	...........
	//初始化pb结构体对象,并读取到pb结构体中
	msg := &stProto.SendMessage{}
	pbErr := proto.Unmarshal(encoded, msg) //反序列化数据
	............

	}
)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章