protobuf介绍和使用

protobuf内容:

1.提供了一个数据结构的通用描述文件的语法,

2.提供的编译器,能够把描述文件定义的类型,翻译成目标语言的类型,并且把描述文件中的所定义的message生成对应的编码解码函数。(生成Java/C++/Lua等不同语言的代码)

3.提供了不同语言的基础运行时库(编码解码函数中最终会调用到这些基础库)

protobuf的动态解析和静态解析:

1.动态解析:可以动态加载协议描述文件,运行的时候对这个协议文件进行解析,解析性能差,但是代码体积小。

2.静态解析:使用protobuf提供的编译器,把协议文件编译成客户端、服务器对应编程语言的代码,项目中都会用一个脚本来生成客户端和服务器代码。解析性能高,代码体积大

protobuf的使用:

第一步:下载protobuf sdk放到项目中,写一个protoManager管理类来使用protobuf的静态解析或动态解析

第二部:编写我们的协议描述文件

第三步:将protobuf runtime库(C++版/Lua版等)内置到项目中

protobuf的优势:

跨语言:protobuf根据协议描述文件,可以生成不同编程语言的数据结构代码(静态解析),我们只需要一份协议描述文件,不需要针对不同语言都写一份消息体。

消息压缩:protobuf可以生成每个协议对应的encode()/decode()代码,(数据结构<——>二进制)encode()/decode()中对消息体积进行压缩。自己实现的话很麻烦

序列化是把一个语言的数据结构转化成二进制数据,反序列化是把二进制转化成一个语言的数据结构,如果自己实现消息序列化和反序列化算法会有以下问题:

1.不同编程语言对其基础数据类型的编码解码的实现不同,不同的语言编写的程序之间进行收发消息时,要写不同编码解码的代码。比如我们的底层代码要完成一些基础数据类型的编码和解码:

float,double,int,string...

2.想要压缩消息体积,每条协议都要写它的encode()和decode()代码。比如某个协议的字段int n = 8;它的数值在一个字节的表示范围内,我们对这个协议编码时候,会把这个字段优化成byte n = 8;

protobuf解决了上面两个问题

protoManager的实现:


import { _decorator, Component, Node, TextAsset } from 'cc';

declare const protobuf: any;

export class ProtoMgr extends Component {
    public static Instance: ProtoMgr = null as unknown as ProtoMgr;
    
    // 协议描述文件的文本对象
    private pbTexAsset: TextAsset|null = null;
    // 根据协议描述文本对象,我们生成一个动态解析的对象;
    private pb: any = null;

    public Init(pbTex: TextAsset|null): void {
        this.pbTexAsset = pbTex;
        this.pb = protobuf.parse(this.pbTexAsset.toString());
    }

    onLoad(): void {
        if(ProtoMgr.Instance === null) {
            ProtoMgr.Instance = this;
        }
        else {
            this.destroy();
            return;
        }
    }
    //msgName协议名
    //msgBody协议体
    public SerializeMsg(msgName: string, msgBody: any): Uint8Array {
        let rs = this.pb.root.lookupType(msgName);
        let msg = rs.create(msgBody);
        let buf = rs.encode(msg).finish();

        return buf;
    }

    public DeserializeMsg(msgName: string, msgBuf: Uint8Array): Object {
        let rs = this.pb.root.lookupType(msgName);
        let msg = rs.decode(msgBuf)

        return msg;
    }
}


// 测试Probuf
// message UnameLoginReq {
//     required string uname = 1;
//     required string upwd = 2;
// }
// 编码
var buf = ProtoMgr.Instance.SerializeMsg("UnameLoginReq", {uname: "blake", upwd: "123456"});
console.log(buf);
// 解码
var msg = ProtoMgr.Instance.DeserializeMsg("UnameLoginReq", buf);
console.log(msg);

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值