protobuf在websocket通讯中的使用

教程目录
一 protobuf简介
二 使用protobuf
三 Demo下载

参考:

CSDN:Egret项目中使用protobuf(protobufjs)

TS项目中使用Protobuf的解决方案(babel)

在cocos creator中使用protobufjs

layabox:网络和格式--ProtocolBuffer

egret protobuf(egret官方提供的工具,自动配置和生成)

protobuf简介
百度百科:protocolbuffer(以下简称PB)是google 的一种数据交换的格式,它独立于语言,独立于平台。google 提供了多种语言的实现:java、c#c++、go 和 python,每一种实现都包含了相应语言的编译器以及库文件。由于它是一种二进制的格式,比使用xml 进行数据交换快许多。可以把它用于分布式应用之间的数据通信或者异构环境下的数据交换。作为一种效率和兼容性都很优秀的二进制数据传输格式,可以用于诸如网络传输、配置文件、数据存储等诸多领域。

参考:protocol buffer_百度百科  中重度游戏开发框架:EGER PRO开发教程
google_protobuf数据类型      


使用protobuf
1  导入第三方库
我直接把protobuf第三方库放在了项目中..
protobuf在websocket通讯中的使用 

修改egretProperties.json文件,增加protobuf库。添加完成后,需要编译引擎。
protobuf在websocket通讯中的使用 

2 编写protobuf文件
新建一个文件template.proto
我这里编写一个测试用数据,user_login
protobuf在websocket通讯中的使用 

3 加载protobuf文件

注意类型要是text
protobuf在websocket通讯中的使用 

4 使用protobuf
读取template_proto文件

[C++] 纯文本查看 复制代码

1

var message = dcodeIO.ProtoBuf.loadProto(RES.getRes("template_proto"));



新建一个user_login类

[AppleScript] 纯文本查看 复制代码

1

2

3

4

var user_login_class = message.build("user_login");

var user_login = new user_login_class();

user_login.userId = 123;

user_login.userName = "peter";



将user_login转成字节

[C#] 纯文本查看 复制代码

1

var bytes = user_login.toArrayBuffer();



socket发送user_login

[C#] 纯文本查看 复制代码

1

2

3

var socket:egret.WebSocket = new egret.WebSocket();

socket.writeBytes(bytes);

socket.flush();



接收数据的处理

1

2

3

4

5

6

//接收服务端数据(假设byteArray是服务端websocket接收数据)

var revData:egret.ByteArray = byteArray;

        

//读取数据

 var user_login = user_login_class.decode(revData.buffer);

console.log("接收数据:", user_login);

  




三 Demo下载

 

 

其他:

1、怎么自动将.proto文件导出成ts文件?有没有现成工具?

比如一个.proto文件里有

1

2

3

4

5

6

7

8

9

message user_login{

    required int32 userId = 1;

    required string userName = 2;

}

 

message user_login2{

    required int32 userId = 1;

    required string userName = 2;

}

怎么导出ts的文件,在egret中直接使用

1

2

3

4

5

6

7

8

9

class user_login{

     public userId:number;

     public userName:string

}

 

class user_login2{

     public userId:number;

     public userName:string

}

 

protobufjs工具

准备一个测试用的.proto文件

protobuf在websocket通讯中的使用

 

在安装了nodejs的情况下,全局安装protobufjs。打开cmd窗口,输入:

1

npm install protobufjs -g

 

然后在你的proto文件的目录下,打开cmd窗口

输入:

1

2

pbjs -t static-module -w commonjs -o template.js template.proto

pbts -o template.d.ts template.js 

protobuf在websocket通讯中的使用

 

 得到如下文件:

 protobuf在websocket通讯中的使用

仅仅是一些测试数据,但是文件达到了80kb+。生成的template.js里的代码太多了。

 protobuf在websocket通讯中的使用

 

生成的文件还有问题。参考:Babel 入门教程

 

 

egret官方提供的工具

下载demo瞅瞅,也是封装protobufjs。

protobuf在websocket通讯中的使用

dist                                     存放了protobuf-library.js库

egret-project                      白鹭项目

egret-project_wxgame      白鹭小游戏项目

out                                     存放cli.js、index.js,用于拷贝protobuf源码到白鹭项目,添加protobuf到egretProperties.json配置文件中等等

src                                     存放index.ts

.gitignore                           忽略文件

package.json、tsconfig.json    其他等等配置文件

 

protobuf在websocket通讯中的使用

 

 

 

根据教程尝试安装。全局安装protobufjs。

1

2

npm install [email protected] -g

npm install @egret/protobuf -g

protobuf在websocket通讯中的使用

 

 在你的白鹭项目下,打开cmd窗口,输入pb-egret add,将代码和项目结构拷贝至白鹭项目中

1

pb-egret add

譬如我的白鹭项目是TTT

protobuf在websocket通讯中的使用

这是会项目目录下会新增一些文件,配置文件也会自动被修改

 

将测试用的.proto文件放在项目目录TTT\protobuf\protofile下

protobuf在websocket通讯中的使用

 

.proto一定要有package 

protobuf在websocket通讯中的使用

 

cmd中输入pb-egret generate,文件将会生成到 protobuf/bundles 文件夹中

1

pb-egret generate

 

生成的文件如下。这是.proto文件转成的js库,已经自动配置到egretProperties.json中了。

protobuf在websocket通讯中的使用

 

 代码中使用(未实际测试)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

//create user_login

let sendData = new template.user_login();

sendData.userId = 1;

sendData.userName = "abc";

 

//encode user_login

let sendByte = template.user_login.encode(sendData).finish();

 

//websocket send

let byteArray:egret.ByteArray = new egret.ByteArray(sendByte);

let socket:egret.WebSocket = new egret.WebSocket();

socket.writeBytes(byteArray);

socket.flush();

 

//decode user_login

let user_login = template.user_login.decode(sendByte);

console.log(user_login.userId,  user_login.userName);  //输出1 "abc"

 

我们打开protobuf-bundles.js,会发现user_login里有有以下方法

create

encode

encodeDelimited

decode

decodeDelimited

fromObject

toObject

toJSON

verify

convert

我们可以对该生成规则进行精简,在生成js文件时,生成指定的方法,减少文件大小

 

精简生成文件

一、首先修改out文件夹下的index.js

讲generate下的case14修改如下

protobuf在websocket通讯中的使用

 

二、再修改项目protobuf文件夹下的pbconfig.json

 修改如下

protobuf在websocket通讯中的使用

三、再次打开cmd窗口pb-egret generate生成一次proto文件

会发现create,verify、convert、delimited方法没有了。

 

四、关于protobuf-bundles.js中的注释,则无需精简,再发布项目时,会自动压缩去掉这些注释。