网络游戏开发系列3

1.4 基于Protobuf的序列化与反序列化技术原理详解

  本节給大家讲解的是网络游戏开发中的序列化与反序列化。当我们要存储/传送一个数据对象的数据的时候,我们要把这个数据对象实例编码成二进制数据,这样就可以把这些二进制进行存储与传送。当我们接收读取这些二进制的时候,我们有可以根据数据把对应的数据对象实例重建出来,这个过程,我们叫做序列化与反序列化。本节将从以下3点来详细的讲解基于Protobuf的序列化与反序列化。如下:

  1. 基于二进制数据序列化与反序列化的基本原理详解;
  2. Protobuf的设计架构与对应工具;
  3. Unity如何集成使用Protobuf;

基于二进制数据序列化与反序列化的基本原理详解

  我们先来通过一个简单的案例,来讲解二进制序列化与反序列化的基本原理。任何一个复杂对象的数据都可以由简单的数据组合而成,比如 Vector3 结构体对象,就是由3个float分量x, y, z组合而成。数据对象的基本数据类型包括有: Int, float, double, string, boolean等。任何对象可以内嵌子对象,或者使用数组来存储多个子对象。子对象与数组,让我们的数据对象的组成关系可以变得非常复杂

  接下来我们以一个对象为例来进行讲解:

Rect对象里面包含了Vector类与Size类子对象, 而这些子对象由基本的数据组成。我们要编码Rect对象,就要先编码Vector对象,再编码Size对象,这样才能得到Rect对象得编码。解下来我们针对Rect对象做编写编码函数,如下:

基本数据类型得编码函数,这个不用变,可以一次性写好,后面反复得使用;

byte[] Float_encode(float) {…}

byte[] Int_encode(int) {…}

byte[] string_encode(string) {…}

byte[] bool_encode(bool) {…}

每个复杂的数据对象的内部结构都是开发者定义的,所以这块必要更具应用有多少个对象,来编写函数实现,而这些函数可以调用基本数据类型的编码函数,最后组合成byte[];

解码也类似,基本的数据类型,可以实现一次解码函数,复杂的对象,都是由开发者自己调用基本数据类型的解码,一个个的解码出来。

经过上面的分析,我们总结如下:

  1. 任何复杂的数据对象与类型,都可以由简单数据类型编码/解码的组合来实现它们的编码解码;
  2. 简单的数据类型的编码和解码,一次编写就可以反复的重复利用;
  3. 复杂数据对象是开发者在开发中定义的,所以每定义一个就要实现对应的编码/解码函数;
  4. 客户端与服务端通讯的时候,编码的可能是C#编程语言,但解码的可能是Java编程语言;

Protobuf的设计架构与对应工具

  上面总结分析出来的这四点,为了解决上面的问题,google 发起了一个protobuf的开源项目。目前我们做网络游戏中序列化、反序列化很多都是基于它来做的。Protobuf解决上序4个问题,主要的设计如下:

  1. 将基本数据类型的二进制数据编码/解码,编写成了固定的函数,形成一个”库”,这个库我们叫做runtime库;
  2. 我们将runtime库实现多个语言版本,支持主流的编程语言;
  3. 为了应对不同的开发时需要的数据类型,不同的编程语言, 推出了Protobuf 协议对象编码规则与语法。我们要定义一个序列化/反序列化对象,就按照这个规则语法实现编写到.proto文件里面,这个我们又叫做协议描述文件。
  4. 编写一个Protoc的编译器,能将我们的协议描述文件中定义的数据对象,按照里面的基本数据类型层层展开,自动生成出对应的编码解码函数。而不用我们开发者自己去写。基本数据类型的编码解码,都是调用runtime库里面的。Protoc还可以生成多个语言版本的编码解码函数。
  5. 开发者只需要将要序列化/反序列化的数据对象定义到协议文件,然后运行编译器生成协议文件对应的目标编程语言的代码, 就可以使用里面的类与对象了。

总结以下, Protobuf包含了:协议编写语法规则,协议编译器,runtime库, 与编译器生成代码。我们根据语法编写好协议,编译器生成对应的代码,对应的代码调用了runtime库中的底层接口。我们项目内置runtime库 + 编译器生成的代码,这样就可以使用这些数据类型,做序列化与反序列化。

Protoc协议编译器,是C/C++开发的,可以生成多个编程语言,在编译protobuf的时候,这个工具也会同时被编译出来。Runtime库代码直接拷贝过去即可。协议代码生成后,放到工程项目中直接使用。代码中直接使用这些生成的数据类型。

Unity如何集成使用Protobuf

Unity项目如何使用Protobuf呢?按照下面的步骤来实现可以了。

  1. 内置C#的protobuf的runtime库代码到Unity项目,复制过来,直接放Unity就可以了。我一般会在Scripts下新建一个3rd文件夹来存放,如下图所示:

  1. 使用cmake源码编译protobuf,来生成protoc的编译工具,如果自己懒得编译,可直接到github上下载已经编译好的protoc。

在Unity Assets文件夹外面定义一个协议生成文件夹,专门用来定义协议文件.proto, 然后运行编译器生成 c#代码,然后再拷贝到项目Assets的指定代码目录下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值