Protobuf数据交换格式

简介

  ProtoBuf(Google Protocol Buffer)是由google公司用于数据交换的序列结构化数据格式,具有跨平台、跨语言、可扩展特性,类型于常用的XML及JSON,
但具有更小的传输体积、更高的编码、解码能力,特别适合于数据存储、网络数据传输等对存储体积、实时性要求高的领域。以 .proto为后缀,有自己的编译器 protoc, protoc2 和 protoc3 版本。
简单理解: 相比json更加高效,高效序列化和反序列化,能够将数据压缩更小的数据交换格式(暂时简单理解为更加高效的强大json)。gRPC默认都是基于protobuf数据格式来进行数据交换,所以
protobuf肯定先学习才能为gRPC学习做好准备。 编写好.protoc文件以后,使用protoc并且根据输入参数,选择要转化语言的类型,就能转化为各个编程语言的代码。

protobuf样例

  接下来也没必要一字一句的把语法给大家过一遍,我把常用到的语法都通过一个protobuf文件来阐述即可,做一个提炼总结。详细文档去官方看就是了。半个小时以内肯定学会,
没想象中那么复杂,和学json差不多。具体内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78

// 注释: 1. //单行注释 2. /* */ 多行注释
syntax = "proto3"; // 明确使用protobuf版本 默认不写 则是proto2
package com.test; // 定义包package

// 官方文档: https://developers.google.com/protocol-buffers/docs/proto3

import "./pk2.proto"; //导入protoW文件

option go_package = "proto"; // 如果使用protoc编译为java代码 则按照这个包名称生成 忽略 com.test
option java_package = "com.hello"; // 如果是编译为go代码 则按照com.hello包名生成

// 定义message信息
message Keyword {
string value = 1;
}

// 定义一个消息message参数
message QueryData{

// 基本数据类型字段定义 基本数据类型都能涵盖 string bool int double bytes等等
string name = 1;
string orderBy = 2;
double weight = 3;
float searchWeight = 4;
int32 type = 5;
uint64 id = 6;
fixed32 type2 = 7;
fixed64 type3 = 8;
bool isOk = 9;
bytes passWord = 10;

// 定义数组 类似 []string
repeated string cases = 11;

// 定义map类型 string=>string
map <string,string> myMap = 15;

// oneof可选字段 里面的字段只能出现一个或者0个
oneof OptionField {
string selectWord = 12;
string queryType = 13;
}

// 定义枚举类型
enum WeekDay {
SUNDAY = 0; // 枚举类型 必须第一个值是0
MONDAY = 1;
TUESDAY = 2;
}
WeekDay selectDay = 14;

// keyword 复合字段类型 引用上面定义好的Keyword类型
Keyword kw = 16;
}

// 定义接口返回message格式
message QueryResponse {
int32 code = 1;
string msg = 2;
string htmlData = 3;
}

// 定义rpc服务 一般指gRPC比较多
service QueryApi {

// 1.grpc中的一元rpc接口 很普通 可以理解为正常的http接口差不多
rpc Query (QueryData) returns (QueryResponse){};

// 2.基于服务端"流式"rpc接口 建立连接以后 服务端可以向客户端发数据
rpc ServerQueryStyle(QueryData) returns (stream QueryResponse) {};

// 3.基于服务端"流式"rpc接口 和第一种不太一样的是 这种方式基于"流"传输 而不是发送一次请求响应后就断开
rpc ClientQueryStyle(stream QueryData) returns (QueryResponse) {};

// 4.基于客户端,服务端"双向流式"rpc接口 全双工通信 双方可以互相发送数据
rpc ClientAndServerStreamQuery(stream QueryData) returns (stream QueryResponse){};
}