目录

  • 1. 前言
  • 2. Protobuf 简介
    • 2.1 Protobuf 优点
    • 2.2 Protobuf 缺点
    • 2.3 Protobuf Golang 安装使用
  • 3. Protobuf 通讯案例
    • 3.1 创建.proto协议文件
    • 3.2 protobuf编解码
    • 3.3 socket通讯
  • 4. Protobuf 基础知识
    • 4.1 简单模板
    • 4.2 简单语法
    • 4.3 注意事项

1. 前言

工作几年了。ITDragon龙 的编程语言从熟悉的Java,到喜欢的Kotlin,最后到一言难尽的Golang。常用的数据交换格式也从xml到json,最后到现在的protobuf。因为底层驱动对数据的采集非常频繁,而且对数据的可读性并没有太高的要求。所以采用序列化体积更小、序列化和反序列化速度更快的protobuf。考虑到后期还会继续深入使用protobuf,先插个眼,方便后期的使用和问题排查。

2. Protobuf 简介

Google Protocol Buffer(简称 Protobuf) 是Google 旗下的一款轻便高效的结构化数据存储格式,平台无关、语言无关、可扩展,可用于通讯协议和数据存储等领域。适合用做数据存储和作为不同应用,不同语言之间相互通信的数据交换格式。

2.1 Protobuf 优点

1.支持多种语言、跨平台,多平台之间只需要维护一套proto协议文件(当然还需要对应的配置)。

2.序列化后是二进制流,体积比Json和Xml小,适合数据量较大的传输场景。

3.序列化和反序列化速度很快,据说比Json和Xml快20~100倍。(ITDragon龙 本地测过,只有在数据达到一定量时才会有明显的差距)

小结:适合传输数据量较大,对响应速度有要求的数据传输场景。

2.2 Protobuf 缺点

1.序列化后的数据不具备可读性。

2.需要一定的额外开发成本(.proto 协议文件),每次修改都需要重新生成协议文件。

3.应用场景并没有Json和Xml广,相对于使用的工具也少。

小结:自解释性较差、通用性较差,不适合用于对基于文本的标记文档建模。

2.3 Protobuf Golang 安装使用

step1:下载protobuf 编译器protoc。下载地址 。

step2:下载对应的文件。Windows系统直接将解压后的protoc.exe放在GOPATH/bin目录下(该目录要放在环境变量中);Linux系统需要make编译。

step3:安装protobuf库文件(因为protoc并没有直接支持go语言)。官方goprotobuf,执行成功后GOPATH/bin目录下会有protoc-gen-go.exe文件

go get github.com/golang/protobuf/proto
go get github.com/golang/protobuf/protoc-gen-go

据说gogoprotobuf库生成的代码质量和编解码性能都比官方的goprotobuf库强,而且完全兼容官方的protobuf。ITDragon龙 我们当然也不能放过它。

step4:安装gogoprotobuf库文件。执行成功后GOPATH/bin目录下会有protoc-gen-gofast.exe文件

go get github.com/gogo/protobuf/proto
go get github.com/gogo/protobuf/gogoproto
go get github.com/gogo/protobuf/protoc-gen-gofast

step5:使用protoc 生成go文件。先移步到xxx.proto文件所在目录,再执行以下任意一个命令

// 官方goprotobuf
protoc --go_out=. *.proto
// gogoprotobuf
protoc --gofast_out=. *.proto

step6:protoc是直接支持Java语言,下载后可以直接使用。

protoc xxx.proto --java_out=./

3. Protobuf 通讯案例

这里用Golang分别实现socket的服务端和客户端,最后通过protobuf进行数据传输,实现一个简单案例。

3.1 创建.proto协议文件

1.创建一个简单的models.proto协议文件

syntax = "proto3";
package protobuf;message MessageEnvelope{int32 TargetId = 1;string ID = 2;bytes Payload = 3;string Type = 4;
}

2.通过protoc生成对应的models.pb.go文件(这个文件内容太多,可读性也差,就不贴出来了)

protoc --gofast_out=. *.proto

3.2 protobuf编解码

package protobufimport ("fmt""github.com/golang/protobuf/proto""testing"
)func TestProtocolBuffer(t *testing.T) {// MessageEnvelope是models.pb.go的结构体oldData := &MessageEnvelope{TargetId: 1,ID:       "1",Type:     "2",Payload:  []byte("ITDragon protobuf"),}data, err := proto.Marshal(oldData)if err != nil {fmt.Println("marshal error: ", err.Error())}fmt.Println("marshal data : ", data)newData := &MessageEnvelope{}err = proto.Unmarshal(data, newData)if err != nil {fmt.Println("unmarshal err:", err)}fmt.Println("unmarshal data : ", newData)}
-----------打印结果-----------
=== RUN   TestProtocolBuffer
marshal data :  [8 1 18 1 49 26 17 73 84 68 114 97 103 111 110 32 112 114 111 116 111 98 117 102 34 1 50]
unmarshal data :  TargetId:1 ID:"1" Payload:"ITDragon protobuf" Type:"2"
--- PASS: TestProtocolBuffer (0.00s)
PASS

3.3 socket通讯

1.TCP Server端

func TestTcpServer(t *testing.T) {// 为突出重点,忽略err错误判断addr, _ := net.ResolveTCPAddr("tcp4", "127.0.0.1:9000")listener, _ := net.ListenTCP("tcp4", addr)for {conn, _ := listener.AcceptTCP()go func() {for {buf := make([]byte, 512)_, _ = conn.Read(buf)newData := &MessageEnvelope{}_ = proto.Unmarshal(buf, newData)fmt.Println("server receive : ", newData)}}()}
}

2.TCP Client端

func TestTcpClient(t *testing.T) {// 为突出重点,忽略err错误判断connection, _ := net.Dial("tcp", "127.0.0.1:9000")var targetID int32 = 1for {oldData := &MessageEnvelope{TargetId: targetID,ID:       strconv.Itoa(int(targetID)),Type:     "2",Payload:  []byte(fmt.Sprintf("ITDragon protoBuf-%d", targetID)),}data, _ := proto.Marshal(oldData)_, _ = connection.Write(data)fmt.Println("client send : ", data)time.Sleep(2 * time.Second)targetID++}
}

4. Protobuf 基础知识

这里记录工作中常用知识点和对应的注意事项,详细知识点可以通过官网查询:https://developers.google.com/protocol-buffers/docs/proto3

4.1 简单模板

举一个简单列子。不同的编程语言的语法差别主要体现在数据类型的不同。

syntax = "proto3";                    // 指定使用proto3语法
package protobuf;                   // 指定包名message MessageEnvelope{             // 定义一个消息模型uint32 TargetId = 1;            // 定义一个无符号整数类型string ID = 2;                   // 定义一个字符串类型bytes Payload = 3;             // 定义一个字节类型MessageType Type = 4;           // 定义一个枚举类型repeated Player Players = 5;    // 定义一个集合对象类型
}enum MessageType {                 // 定义一个枚举类型SYSTEM = 0;                     // 第一个枚举值为零ALARM = 1;
}message Player {...
}

4.2 简单语法

1.syntax : 指定使用proto版本的语法,缺省是proto2。若使用syntax语法,则必须位于文件的非空非注释的第一个行。若不指定proto3,却使用了proto3的语法,则会报错。

2.package : 指定包名。防止不同 .proto 项目间命名发生冲突。

3.message : 定义消息类型。

4.enum : 定义枚举类型。第一个枚举值设置为零。

5.repeated : 表示被修饰的变量允许重复,可以理解成集合、数组、切片。

6.map : 待补充

7.Oneof : 待补充

8.定义变量 : (字段修饰符) + 数据类型 + 字段名称 = 唯一的编号标识符;

9.编号标识符 :在message中,每个字段都有唯一的编号标识符。用来在消息的二进制格式中识别各个字段,一旦使用就不能够再改变。[1,15]之内的标识符在编码时占用一个字节。[16,2047]之内的标识符占用2个字节。

10.变量类型:以下来源网络整理

.proto Notes Go Java C++ C# Python
double float64 double double double float
float float32 float float float float
int32 使用变长编码,对于负值的效率很低,如果你的域有可能有负值,请使用sint64替代 int32 int int32 int int
uint32 使用变长编码 uint32 int uint32 uint int/long
uint64 使用变长编码 uint64 long uint64 ulong int/long
sint32 使用变长编码,这些编码在负值时比int32高效的多 int32 int int32 int int
sint64 使用变长编码,有符号的整型值。编码时比通常的int64高效。 int64 long int64 long int/long
fixed32 总是4个字节,如果数值总是比总是比228大的话,这个类型会比uint32高效。 uint32 int uint32 uint int
fixed64 总是8个字节,如果数值总是比总是比256大的话,这个类型会比uint64高效。 uint64 long uint64 ulong int/long
sfixed32 总是4个字节 int32 int int32 int int
sfixed64 总是8个字节 int64 long int64 long int/long
bool bool boolean bool bool bool
string 一个字符串必须是UTF-8编码或者7-bit ASCII编码的文本。 string String string string str /unicode
bytes 可能包含任意顺序的字节据。 []byte ByteString string ByteString str

4.3 注意事项

1.整数数据类型区分好有符号和无符号类型,建议少用万金油式的int32。

2.将可能频繁使用的字段设置在[1,15]之内,也要注意预留几个,方便后期添加。

Golang 使用Protocol Buffer 案例相关推荐

  1. 使用hessian+protocol buffer+easyUI综合案例--登陆

    首先先简单介绍下hessian ,protocol buffer, easyUI框架 hessian: Hessian是一个轻量级的remoting on http工具,采用的是Binary RPC协 ...

  2. gRPC amp; Protocol Buffer 构建高性能接口实践

    介绍如何使用 gRPC 和 ProtoBuf,快速了解 gRPC 可以参考这篇文章第一段:gRPC quick Start. 接口开发是软件开发占据举足轻重的地位,是现代软件开发之基石.体现在无论是前 ...

  3. Protocol Buffer入门——轻松搭建java环境 .

    http://blog.csdn.net/xyz317100759/article/details/6261236 2011-03-19 15:44 1185人阅读 评论(5) 收藏 举报 由于项目的 ...

  4. Java与C++进行系统间交互:Protocol Buffer

    在一次项目中,因笔者负责的java端应用需要与公司C++系统进行交互,公司选定Protocol Buffer方案,故简单的了解一下 有需要的可以看一下其他作者的文章,了解一下Protobuf: htt ...

  5. gRPC in ASP.NET Core 3.x -- Protocol Buffer, Go语言的例子(上)

    前两篇文章半年前写的: gRPC in ASP.NET Core 3.0 -- Protocol Buffer(1), gRPC in ASP.NET Core 3.0 -- Protocol Buf ...

  6. protocol buffer开发指南

    ProtoBuf 是一套接口描述语言(IDL)和相关工具集(主要是 protoc,基于 C++ 实现),类似 Apache 的 Thrift).用户写好 .proto 描述文件,之后使用 protoc ...

  7. 知心王姐小饭桌 IM消息应用开发:一看看懂Protocol Buffer(协议篇)

    前言 由于笔者业团队的业务对即时通讯服务有很大的依赖,春节结束后的第一天,红包没到,产品同学先到了,产品同学和我说要做一款IM,看到需求文档后和设计图后笔者大吃一斤 这不就是一个翻版的web qq吗? ...

  8. 【C++】Google Protocol Buffer(protobuf)详解(一)

    1.简介 Google Protocol Buffer( 简称 Protobuf) 是 Google 公司内部的混合语言数据标准, Protocol Buffers 是一种轻便高效的结构化数据存储格式 ...

  9. Protocol Buffer Basics: C#

    Protocol Buffer 基础知识:c#    原文地址:https://developers.google.com/protocol-buffers/docs/csharptutorial 这 ...

最新文章

  1. 吴恩达:机器学习毕业后,如何规划职业生涯?
  2. 如何清空DNS缓存Windowslinux
  3. 485有时候从机接收指令没反应_原来微信发语音不好听,是你没掌握这2个技巧!快去试试吧...
  4. Qt第三方库QCustomPlot——认识图表的各个部分
  5. QT开发的程序的发布
  6. C语言abc输出最小值改错题,C语言程序设计
  7. python脚本语言采用声音作为手段_python 利用pyttsx3文字转语音过程详解
  8. skype自动回复_如何在Windows 10上阻止Skype自动启动
  9. mysql8.0.20 64位安装教程_MySQL8.0.20压缩版本安装教程图文详解
  10. [转载] 的士速递3
  11. android BaseAdapter优化
  12. 高通骁龙cpu排行_最新手机性能排行榜出炉:高通骁龙865霸榜,前十不见华为!...
  13. Java /Jsp 执行操作系统命令 windows/Linux
  14. RabbitMQ安装问题
  15. cocos2dx报错OpenGL error 0x0501
  16. 【乐理学习笔记】音符时值和拍号
  17. 热血传奇之周星弛[转载]【出处:未知】
  18. 【观察】帆软:扎根于BI,收获于未来
  19. PowerDesigner创建概念模型转换为物理模型使表生成sql
  20. RJS参考之JavaScriptCollectionProxy

热门文章

  1. 风险评估资产重要性识别_如何有效的进行风险评估?
  2. python爬虫php_PHP爬虫编写
  3. bootstrap设置button不显示_电脑便签怎么显示不关闭?电脑云便签敬业签怎么设置显示桌面?...
  4. linux mysql dns_Linux下搭建DNS服务器及踩坑
  5. python爬虫基本知识_爬虫 (十三) 学习 python 基础知识点的正确姿势 (六)
  6. matlab循环矢量化 嵌套,在Matlab中对for循环进行矢量化,得到不同结果的看似等效的代码...
  7. linux shell oracle脚本_领导:如何用shell脚本统计Oracle数据库进程明细和存储过程信息...
  8. 什么是m叉树_国考临近考试了,感觉已经没有进步空间了,最后关头还有没有什么提成成绩的好方法?...
  9. aoe网最早开始时间和最迟开始时间_关键路径(AOE)网 通俗易懂
  10. boa服务器如何运行cgi,嵌入式WEB服务器BOA+CGI.ppt