zoukankan      html  css  js  c++  java
  • 【咸鱼教程】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第三方库放在了项目中..
     

    修改egretProperties.json文件,增加protobuf库。添加完成后,需要编译引擎。
     

    2 编写protobuf文件
    新建一个文件template.proto
    我这里编写一个测试用数据,user_login
     

    3 加载protobuf文件

    注意类型要是text
     

    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();



    接收数据的处理

    //接收服务端数据(假设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文件里有

    message user_login{
        required int32 userId = 1;
        required string userName = 2;
    }
    
    message user_login2{
        required int32 userId = 1;
        required string userName = 2;
    }
    

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

    class user_login{
         public userId:number;
         public userName:string;  
    }
    
    class user_login2{
         public userId:number;
         public userName:string;  
    }
    

    protobufjs工具

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

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

    npm install protobufjs -g
    

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

    输入:

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

     得到如下文件:

     

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

     

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

    egret官方提供的工具

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

    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    其他等等配置文件

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

    npm install protobufjs@6.8.4 -g
    npm install @egret/protobuf -g
    

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

    pb-egret add
    

    譬如我的白鹭项目是TTT

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

    将测试用的.proto文件放在项目目录TTTprotobufprotofile下

    .proto一定要有package 

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

    pb-egret generate
    

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

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

            //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文件夹下的pbconfig.json

     修改如下

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

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

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

  • 相关阅读:
    树链剖分 (模板) 洛谷3384
    ST表 (模板) 洛谷3865
    IOI 2005 River (洛谷 3354)
    IOI 2005 River (洛谷 3354)
    poj1094 Sorting It All Out
    poj1094 Sorting It All Out
    spfa(模板)
    HAOI 2006 受欢迎的牛 (洛谷2341)
    HAOI 2006 受欢迎的牛 (洛谷2341)
    洛谷1850(NOIp2016) 换教室——期望dp
  • 原文地址:https://www.cnblogs.com/gamedaybyday/p/9219946.html
Copyright © 2011-2022 走看看