作者:天使哥特式 | 来源:互联网 | 2023-05-18 04:06
NetMsg为TDEngine传输数据的数据结构
数据组成
包头
数据的前12位为包头
前4位为数据包的长度,供数据读取的时候获取读取的长度
接下来2位为seq_fd,客户端与网关服通讯时会保证包序是正常的,即下一个包的seq是符合标准的,防止作弊重复发送包,在网关服与逻辑服通讯时seq_fd表示网关服接受客户端的fd值。逻辑服根据seq_fd值来获取用数据包的来源用户。
其它字段为预留字段,后续可能有加密字段
包数据
包数据的第一个元素存储的是一个str的值,也就是数据包的名称,可根据数据包的名称获取有几个参数,参数的类型为何种类型,用以数据验证。
接下来为若干个数据值,数据为小端结构
数据值解析
读取字段
首先读取字段头,字段头为两个16进制的值,第一个16进制为index,第二个16进制对应类型的pattern
若为map类型的数据,第一个index用来解析对应的key的字符串值,对于其它类型index固定为0,不作解析
第二个pattern类型则表示下一个值的数据类型,程序会根据pattern值进行下一步值的解析
类型解析
若类型为u8,i8,则会读取后面1个字节做为值
若类型为u16,i16,则会读取后面2个字节做为值
若类型为u32,i32,则会读取后面4个字节做为值
若类型为float,则会读取后面4个字节做为i32值,然后把这个值除以1000得出float的值,float没有用内存直接做转换,只保留了3位的精度,若精度要求高的请勿使用此类型,可在打包的时候转成字符串,解析的时候做相应的解析
若类型为str,raw,则后面2个字节为字符串的长度,再根据长度读取相应的字节做为字符串的值
若类型为map
- 遍历字段头,若头为nil类型,则表示读完map,退出循环,跳到5
- 根据字段头,读取相应的类型
- 根据字段头的index,从配置中读取相应的key,若配置中不存在key,则继续执行1
- 把key和相应的值存到HashMap,继续执行1
- 数据成功读取
若类型为数组类型
- 得出对应的子类型,如u8[]对应的子类型为u8
- 遍历读取字段的值,若读取到的类型为None,退出循环,跳到4
- 把读取到的值存在Vector,继续执行1
- 数据成功读取
至此,数据解析完成
项目地址
TDEngine
td_proto rust 实现
td_proto cpp 实现