[zinx]
<1.Building Basic Services with Zinx Framework>
<2. Zinx-V0.2 Simple Connection Encapsulation and Binding with Business>
<3.Design and Implementation of the Zinx Framework's Routing Module>
<4.Zinx Global Configuration>
<5.Zinx Message Encapsulation Module Design and Implementation>
<6.Design and Implementation of Zinx Multi-Router Mode>
<7. Building Zinx's Read-Write Separation Model>
<8.Zinx Message Queue and Task Worker Pool Design and Implementation>
<9. Zinx Connection Management and Property Setting>
[ZINX应用程序 - MMO游戏案例研究]
<10. Application Case Study using the Zinx Framework>
<11. MMO Online Game AOI Algorithm>
12.Data Transmission Protocol: Protocol Buffers
MMO游戏源代码
https://github.com/aceld/zinx/tree/master/zinx_app_demo/mmo_game
在服务器端项目的当前部分中,使用协议缓冲区表示客户端和服务器之间的通信的数据协议。本节将对协议缓冲区的安装和基本用法提供单独的介绍。如果读者已经熟悉协议缓冲器语法和相关协议,则可以跳过此部分。
12.1协议缓冲区简介
Google协议缓冲区通常称为Protobuf,是由Google开发的轻巧有效的结构化数据存储格式。它是平台 - 敏捷的,语言敏捷的,可扩展的,可用于各种域,例如通信协议和数据存储。这使其适用于不同应用程序的数据存储和使用。它也非常适合不同语言之间的数据交换。通过实现通常在“ .proto”文件中定义的相同协议格式,可以将其编译到不同的语言版本中并集成到各个项目中。这使不同的语言能够使用Protobuf序列化数据。目前,官方网站为C/C ++,Python,Java,Go等语言提供支持。 Google开源协议缓冲区于2008年7月7日。
12.2数据交换格式
ProtoBuf
本质上是一种数据交换格式,它是基于应用程序协议构建的数据协议层。这与本书中先前讨论过的TLV协议不同。数据交换格式具有较高的可读性和数据组装功能。但是,权衡是他们的解析性能往往相对较差。 ProtoBuf
的设计具有优化,专门针对性能方面。
ProtoBuf
的相对优势包括:
(1)序列化导致与JSON和XML相比,数据量较小,使其适用于网络传输。
(2)支持跨平台和多语言用法。
(3)良好的消息格式升级和兼容性。
(4)快速序列化和避免速度,比JSON处理速度快。
ProtoBuf
的相对缺点包括:
(1)与XML和JSON相比,采用较少的广泛采用。
(2)二元格式导致可读性较差。
(3)缺乏自我描述。
12.3安装Protobuf环境
本节主要涵盖Linux(Ubuntu)平台上Golang编程语言的Protobuf环境的安装。对于其他操作系统,您可以参考其他资源或官方文档。
12.3.1安装Protobuf编译工具
步骤1:下载Protobuf源代码:
Step 1: Download the Protobuf source code:
另外,您可以直接提取压缩软件包:
unzip protobuf.zip
步骤2:安装所需的库依赖项:
sudo apt-get install autoconf automake libtool curl make g++ unzip libffi-dev -y
步骤3:生成配置配置文件:
cd protobuf/
./autogen.sh
步骤4:配置环境:
./configure
步骤5:编译源代码(此过程可能需要一段时间):
make
步骤6:安装与Protobuf相关的可执行文件:
sudo make install
步骤7:刷新Protobuf要求的动态库。此步骤对于避免动态库路径关联失败至关重要,该失败可能会阻止与Protobuf相关的命令程序开始:
sudo ldconfig
步骤8:通过执行以下命令来测试ProtoBuf是否成功安装了:
protoc -h
如果它显示预期信息而没有任何错误,则该安装成功。
12.3.2安装Protobuf GO语言插件
由于Protobuf不直接支持GO编程语言,因此开发人员需要手动安装相关的插件。
步骤1:获取原始软件包(GO语言的proto api接口)
go get -v -u github.com/golang/protobuf/proto
go get -v -u github.com/golang/protobuf/protoc-gen-go
步骤2:编译Golang支持插件的代码
cd $GOPATH/src/github.com/golang/protobuf/protoc-gen-go/
go build
步骤3:放置生成的protoc-gen-go可执行文件
将生成的protoc-gen-go可执行器放入 /bin目录(或任何其他$路径目录)中:
sudo cp protoc-gen-go /bin/
12.4 Protobuf语法
Protobuf通常将用户定义的结构类型称为“消息”。 Protobuf消息的定义通常写在带有“ .proto”扩展名的文件中。
12.4.1一个简单的例子
下面是Protobuf文件的一个示例。您可以将其命名为“ file.proto”。文件的内容如下:
//file.proto
syntax = "proto3"; // Specify version information, an error will occur if not specified
package pb; // Package name for generating Go files later
// 'message' is a keyword, used to define a message type
message Person {
string name = 1; // Name
int32 age = 2; // Age
repeated string emails = 3; // Email addresses (repeated indicates the field allows duplicates)
repeated PhoneNumber phones = 4; // Phone numbers
}
// 'enum' is a keyword, used to define an enumeration type
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
// 'message' is a keyword, used to define a message type that can be nested within another message type
message PhoneNumber {
string number = 1;
PhoneType type = 2;
}
原始文件必须具有几个基本元素:
在文件的顶部,需要有一个语法版本信息。在当前的项目示例中,使用的原始版本为“ Proto3”。
软件包声明,指定用于生成GO文件的软件包名称。在使用Golang应用程序的情况下,这通常是相关的。
12.4.2消息格式说明
一条消息由字段组成,消息中每个字段的格式如下:
(字段修改器 +)数据类型 +字段名称 +唯一数字标签
唯一的数字标签,例如Phonenumber中的1和2:
message PhoneNumber {
string number = 1;
PhoneType type = 2;
}
代表消息中每个字段的唯一标识符。这些数字标签用于以消息的二进制格式识别字段,并且不能在同一消息中重复。定义消息后,这些标签将无法更改。
12.4.3数据类型
表21-1解释了Protobuf协议支持的数据类型及其在Golang中的相应类型:
表12-1:Protobuf数据类型
.proto type | go type | 注释 |
---|---|---|
双 | float64 | 64位浮点数 |
float | float32 | 32位浮点数 |
int32 | int32 | 可变长度编码;负效率低下;如果可能的话,请使用sint64进行负值 |
uint32 | uint32 | 可变长度编码 |
uint64 | uint64 | 可变长度编码 |
sint32 | int32 | 可变长度编码;负值比INT32高得多 |
sint64 | int64 | 可变长度编码;签名整数值;比标准INT64 | 更有效编码
固定32 | uint32 | 4个字节;如果该值始终大于228 | ,则比UINT32更有效
固定64 | uint64 | 8字节;如果该值始终大于256 | ,则比UINT64更有效
sfixed32 | int32 | 4个字节 |
sfixed64 | int64 | 8字节 |
bool | bool | 1个字节 |
字符串 | 字符串 | 字符串必须为UTF-8或7位ASCII编码文本 |
字节 | []字节 | 可能包含字节的任意序列 |
在上表中,如果您需要在Golang中定义数据类型,则可以参考Proto协议文件中定义的相应的“ .proto类型”。
12.4.4默认值
正在解析消息并且编码信息不包括特定元素时,解析对象中的相应字段设置为默认值。不同的数据类型具有表12-2中指定的默认值:
表12-2:Protobuf默认值
数据类型范围 | 默认值 |
---|---|
字符串类型 | 默认值是一个空字符串 |
二进制类型 | 默认值是一个空字节数组 |
布尔类型 | 默认值为false |
数字类型 | 默认值为0 |
12.5编译Protobuf
您可以使用协议编译器将文件编译为代码,如下所示:
$ protoc --proto_path=IMPORT_PATH --go_out=DST_DIR path/to/file.proto
在上述命令中,“原始”指令是先前安装的Protobuf协议的编译器。这两个参数定义如下:
(1)--proto_path
指定从“ .proto”文件导入软件包的路径。可以指定多个路径。如果被忽略,默认情况下假定当前目录。
(2)--go_out
指定了将放置生成的GO语言代码文件的文件夹。
开发人员还可以使用以下方法同时编译多个.proto文件:
protoc --go_out=./ *.proto
在编译期间,Protobuf编译器将从“ .proto”文件中生成“ .pd.go”文件。这些文件不应由开发人员修改。如果需要更改,则应编辑“ .proto”文件,然后重新编译。可以在程序代码中直接导入和引用“ .pd.go”文件。它们包括预定义的数据结构和相关方法。
12.6使用Protobuf协议的Golang编程
在上一节中,Protobuf文件将软件包定义为“ PB”,并且生成的PB文件放在当前路径下的“ protoctbuffer_excise”目录中。现在,您可以编写Golang代码以利用定义的数据协议。代码如下所示:
package main
import (
"fmt"
"github.com/golang/protobuf/proto"
"protocolbuffer_excise/pb"
)
func main() {
person := &pb.Person{
Name: "Aceld",
Age: 16,
Emails: []string{"https://github.com/aceld", "https://yuque.com/aceld"},
Phones: []*pb.PhoneNumber{
&pb.PhoneNumber{
Number: "13113111311",
Type: pb.PhoneType_MOBILE,
},
&pb.PhoneNumber{
Number: "14141444144",
Type: pb.PhoneType_HOME,
},
&pb.PhoneNumber{
Number: "19191919191",
Type: pb.PhoneType_WORK,
},
},
}
data, err := proto.Marshal(person)
if err != nil {
fmt.Println("marshal err:", err)
}
newdata := &pb.Person{}
err = proto.Unmarshal(data, newdata)
if err != nil {
fmt.Println("unmarshal err:", err)
}
fmt.Println(newdata)
}
上面的代码现在可以使用定义的“人”数据协议。 Marshal()
方法将内存中的“人”结构编码为序列化的原始数据。 Unmarshal()
方法将序列化的二进制数据解析为“人”结构以用于业务代码。
MMO游戏源代码
https://github.com/aceld/zinx/tree/master/zinx_app_demo/mmo_game
[zinx]
<1.Building Basic Services with Zinx Framework>
<2. Zinx-V0.2 Simple Connection Encapsulation and Binding with Business>
<3.Design and Implementation of the Zinx Framework's Routing Module>
<4.Zinx Global Configuration>
<5.Zinx Message Encapsulation Module Design and Implementation>
<6.Design and Implementation of Zinx Multi-Router Mode>
<7. Building Zinx's Read-Write Separation Model>
<8.Zinx Message Queue and Task Worker Pool Design and Implementation>
<9. Zinx Connection Management and Property Setting>
[ZINX应用程序 - MMO游戏案例研究]
<10. Application Case Study using the Zinx Framework>
<11. MMO Online Game AOI Algorithm>
12.Data Transmission Protocol: Protocol Buffers
作者:
不和谐:https://discord.gg/xQ8Xxfyfcz
zinx:https://github.com/aceld/zinx
github:https://github.com/aceld
Aceld的家:https://yuque.com/aceld