找回密码
 立即注册
查看: 246|回复: 5

菜鸟教程|在Egret Engine中如何使用Protobuf

[复制链接]
发表于 2023-3-1 05:17 | 显示全部楼层 |阅读模式
现在在网络通信和通用数据交换等应用场景中经常使用的技术是 JSON 或 XML以及 Google  的 Protobuf。Protobuf是后起之秀,其在效率、兼容性等方面更加出色。很多人在项目技术选项中,尤其是网络通信、通用数据交换等场景应该会优先选择Protobuf。
白鹭引擎首席架构师王泽曾经发布了一个开源项目Protobuf-egret,提供了一个可以适配微信小游戏的Protobuf 类库以及对应的代码生成工具,并且这个工具不仅限于白鹭引擎,即使是使用其他 HTML5 游戏引擎的开发者也可以使用。本文将从基础讲解,让大家认识Protobuf和如何在自己的项目中使用Protobuf这种数据格式以及开源项目Protobuf-egret开源库的使用。
1、什么是Protobuf

Protobuf是Google开源的一款类似于Json,XML数据交换格式,其内部数据是纯二进制格式,不依赖于语言和平台,具有简单,数据量小,快速等优点.
2、Protobuf与XML,Json的比较

1、json: 一般的web项目中,最流行的主要还是json。因为浏览器对于json数据支持非常好,有很多内建的函数支持。  2、XML: 在webservice中应用最为广泛,但是相比于json,它的数据更加冗余,因为需要成对的闭合标签。json使用了键值对的方式,不仅压缩了一定的数据空间,同时也具有可读性。  3、Protobuf:是谷歌开源的一种数据格式,适合高性能,对响应速度有要求的数据传输场景。
相对于其它Protobuf更具有优势  1:序列化后体积相比json和XML很小,适合网络传输  2:支持跨平台多语言  3:消息格式升级和兼容性还不错  4:序列化反序列化速度很快,快于Json的处理速度
结论:  在一个需要大量的数据传输的场景中,如果数据量很大,那么选择Protobuf可以明显的减少数据量,减少网络IO,从而减少网络传输所消耗的时间。
3、Protobuf如何使用

因为profobuf是二进制数据格式,需要编码和解码。数据本身不具有可读性。因此只能反序列化之后得到真正可读的数据。那么,在项目中如何使用呢?
首先,编写Protobuf格式的消息文件(以.proto为后缀的文件);
下面就是我编写的一个test.proto文件
syntax = "proto3";//语法是proto3的语法
package test;//给每一个文件指定一个package值。

//每一个数据结构就是一个消息 有message关键字定义
message user_login{
  //限定修饰符 | 数据类型 | 字段名称 = | 字段编码值 | [字段默认值]
        required int32 userId = 1;
        required string        userName = 2;
  require string password = 3;
}
ps:更多的语法规则大家可以百度查看,这里不详细讲解了。
其次,使用Protobuf的编译器编译消息文件XXX.proto;
google 提供了多种语言的实现:C++、C#、Objective-C、Java、JavaScript、Ruby、PHP、Dart、Go 语言,每一种实现都包含了相应语言的编译器以及文件。
最后,使用编译好对应语言的类文件进行消息的序列化和反序列化
4、egret集成Protobuf

如何在egret游戏项目中使用Protobuf数据格式进行网络通信和数据交换呢?
白鹭引擎首席架构师王泽曾经发布了一个开源项目Protobuf-egret,提供了一个可以适配微信小游戏的Protobuf 类库以及对应的代码生成工具,并且这个工具不仅限于白鹭引擎,即使是使用其他 HTML5 游戏引擎的开发者也可以使用。相关内容大家可以再次阅读《如何在微信小游戏中使用Protobuf》(https://mp.weixin.qq.com/s/WNdIRxZEfpKFpUdFdlr5Mg)。接下来,我再更加详细的介绍一下我的使用过程。
4.1 介绍egret Protobuf库

特性


  • 提供 Protobuf.js 基础运行时库
  • 提供命令行脚本,将 protofile 生成 JavaScript 代码
  • 生成正确的 .d.ts 代码,以方便 TypeScript 项目使用
  • 一键配置白鹭引擎的配置文件,无需开发者手动修改配置即可在项目中直接集成
  • 本项目虽然名为 egret Protobuf ,但是理论上支持所有 HTML5 游戏引擎。欢迎使用 PIXI.js , Cocos2d-js , LayaAir 等其他引擎的开发者使用本库。
原理

封装了 Protobufjs 库及命令行。使用 Protobufjs 6.8.4 的运行时库。
Protobufjs 自身存在着 pbts 命令,虽然也可以生成 .d.ts 文件,但是在全局模式而非 ES6 module 的情况下存在一些错误,本项目致力于解决这个问题,使 Protobufjs 可以在非 ES6 模块项目中(比如白鹭引擎)中也可以使用 Protobufjs
Protobufjs 提供了多种使用方式,由于微信小游戏禁止 eval , new Function 等动态代码形式,所以本项目只提供了生成代码的形式,不支持通过 Protobuf.load('awesome.proto') 的方式(因为这种方式也无法在微信小游戏中运行)。
4.2 安装egret Protobuf库

第一步,首先检查你是否安装了node.js以及npm,没有安装的自行安装。


第二步,在自己的电脑上安装Protobufjs库以及egret Protobuf库。
Protobuf.js是基于ByteBuffer.js的Protocol Buffers纯JavaScript实现,主要功能是解析.proto文件,构建Message类,编码解码。
#安装protobufjs库
npm install protobufjs@6.8.4 -g
#安装egret protobuf库
npm install @egret/protobuf -g4.3 使用egret Protobuf库

假设用户有个名为 egret-project 的白鹭项目;
第一步,cd到egret-project目录下
cd egret-project第二步,将egret Protobuf代码以及项目结构拷贝至白鹭项目
pb-egret add执行之后的项目目录如下图:


第三步,将XXX.proto文件拷贝至protofile目录中。



第四步,将XXX.proto文件在peorobuf/bundles目录下生成对应的js文件和d.ts文件。
pb-egret generate

4.4 认识Protobuf-bundles.d.ts



我们看看Protobuf如何序列化和反序列化
Main.ts
         var user = {
            "userId":1,
            "userName":"psyche"
        }
        //验证user是否满足要求
        var ret = test.user_login.verify(user);
        console.log(ret);
                                //如果正确,ret是null 否则是返回字符串
        if(ret){
            throw Error(ret);
        }
                       
        var msg = test.user_login.create(user);
        console.log(msg);
                                //将实例编译成二进制流
        var buf = test.user_login.encode(user).finish();
        console.log(buf);
                                //解析二进制流
        var de_buf = test.user_login.decode(buf);
        console.log(de_buf);本次关于egret中使用Protobuf的介绍到此为止。
案例链接:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
发表于 2023-3-1 05:24 | 显示全部楼层
我成功引入了,但有几个问题。npm install Protobufjs@6.8.4 -g 和 npm install @egret/Protobuf -g 都应该是小写的protobufjs。

然后pb-egret generate 生成的protobuf-bundles.d.ts 文件的里的verify方法有问题,编译不过,我之前搞protobufjs库的时候用过这个函数,这个函数是其实没什么用的,我直接注释掉就行了,接着测试一下,没问题。
发表于 2023-3-1 05:25 | 显示全部楼层
收到,谢谢提醒!
发表于 2023-3-1 05:25 | 显示全部楼层
还有一个贼坑爹的问题啊。我用完整的proto文件进行测试的时候,pb-egret generate 生成的代码一堆语法错误,根本无法通过编译。太坑爹了,在我万念俱灭的时候,在论坛里搜到一个相关的帖子,一个老哥给出了回答,我真的谢谢他祖宗十八代,原帖地址:用pb-egret转的protobuf代码编译报错-Egret社区-技术问答-白鹭引擎-Egret Engine-免费开源HTML5游戏引擎 - Powered by Discuz! 。

解决方法就是要用node 11.8.0 的版本,也不知道这老哥是怎么琢磨出来的。

配合node 11.8.0 版本的node ,pb-egret generate 是支持 protobuf 3版本的,我已经测试过了。
发表于 2023-3-1 05:30 | 显示全部楼层
Index of /download/release/v11.8.0/ 顺便贴一个node v11.8.0 的地址,以便有需要的网友
发表于 2023-3-1 05:34 | 显示全部楼层
是的,确实需要配合指定的node版本使用,感谢告知!
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-11-24 03:36 , Processed in 0.118877 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表