pomelo源码解析之模块解析(二)

pomelo-protobuf解析

官方wiki:https://github.com/NetEase/pomelo/wiki/消息压缩
protobuf是一种序列化技术,能够大大减少传输无效数据

为什么可以减少传输无效数据

先看一下传统的C++通信格式

#pragma pack(1)
struct player
{
 char name[32];
 int sex;
};
#pragma pack()

因为名字有长有短,需要定义一个字符数组。也就是这个消息必然会发送32+4=36个字节。实际运用中会有很多的浪费。
而protobuf所采用的数据格式会去掉那些无效的数据,可以很大的压缩整个消息流的长度。
同时也更方便的使用变长字符串。与json相比,不需要在消息流中定义变量名字。

所采用编码格式

采用variant编码。第一个字节标视后续数据的tag以及type。
后续每个字节的最高位为控制位,剩余7位存储数据。如果最高位位1,代表下一个字节依旧为本次的数据。

例如传输一个 unsigned int a = 1
这个a变量序列化后的二进制为两个字节 (pomelo-protobuf采用的是小端格式,以小端存储为例,下同)

第一个字节:其中第一位flag,中间4位表示tag(用户设置,4位表示不下怎么办看最后),最后3位表示type,也就是说最多支持2^3=8种类型

flag tag type
0 xxxx 000

flag之后的字节是具体的value,最高位是标志位,为1的话表示下一个字节依旧为本次的数据

flag value
0 0000001

如果传输的数据大于127,例如200的二进制表示为11001000。序列后为3个字节,第一个字节同上。第二三个字节如下:

flag value
1 1001000
flag value
0 0000001

有符号整型的话。如果是整数,直接*2存储 负数的话 *2-1存储。取值的话根据%2的余数判断符号

字符串的话,需要在flag之后的字节写入长度

怎么使用

在项目/config 内有clientProtos.jsonserverProtos.json两个配置文件,分别对应客户端的消息和服务器的消息
配置格式:支持required message repeated关键字 查看源码得知optional与required关键字功能相同

{
   
	"onMove" : {
   
		"required uInt32 entityId" : 1,
		"message Path": {
   
		  "required double x" : 1,
		  "required double y" : 2
		},
		"repeated Path path" : 2,
		"required float speed" : 3
	  }
}

上文定义了一个onMove的消息。里面包含有3个字段 entityId path speed。最后的数字就是tag(不允许重复)
其中path为自定义类型。也就是message定义的类型。并且是个数组。
翻译成C++是这样的:

struct Path
{
	double x;
	double y;
};
struct onMove
{
	unsigned int entityId;
	Path path[];  // 未知数量
	float speed;
};

pomelo-protobuf内置数据类型:pomelo-protobuf/lib/constant.js

module.exports = {
   
	TYPES : {
   
		uInt32 : 0,
		sInt32 : 0,
		int32 : 0,
		doub
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值