Lua Protocol
使用Lua Table语法定义协议模板。
设计由来
使用Lua开发游戏已经有两年多了,最初接触到的网络交互协议是由老大设计的。只支持整数和字符串类型的数据,后面的主程添加了元素为Lua表的数组类型的数据。主要核心在于Buffer的存储形式:
- 整数分
int8
,int16
,int32
,int64
类型存储,
- 整数前面有1byte表示正负数和整数位数,
- 字符串则是前面存字符串的长度。
- 序列化时不存储key,只存value。
- 协议的序列化和反序列化都需要依靠协议模板,称之为
schema-full
(有模式的序列化方式)
添加新类型
我现在添加了表,浮点数,完整的数组。
- 数组元素必须是同种类型,类似于C语言数组
- 数组元素可以是任意支持的类型
- 序列化数组时,先存数组的长度
- 表的key必须是字符串
- 导入协议结构时会将表的key排序存储
- 序列化表则是每个元素按key的顺序逐个存储
定义协议语法
- 使用Lua Table的语法
- 根据默认值区分整数和浮点数
- 整数:
n==math.floor(n)
例如:1.0,1,2.00
- 浮点数:
n~=math.floor(n)
例如:1.1,0.1,1.23
- 字符串:Lua的string类型
- 表:只支持key为string类型的table
- 数组:定义第一个元素
- 如下完整示例:
local proto_struct = {
tbl_data = {
int_data = 0,
float_data = 0.1,
str_data = "default string",
int_array = {1},
float_array = {1.1},
str_array = {""},
},
tbl_array = {
{
name = "tbl_array_element",
id = 1,
},
},
}
Buffer格式
int 类型
sign |
1byte |
1byte |
- |
0xF1 |
0x00~0xFF |
+ |
0x01 |
0x00~0xFF |
- (3bytes)[-65535,-256],[+256,+65535]
sign |
1byte |
2byte |
- |
0xF2 |
0x0100~0xFFFF |
+ |
0x02 |
0x0100~0xFFFF |
- (5bytes)[-4294967295,-65536],[+65536,+4294967295]
sign |
1byte |
4byte |
- |
0xF3 |
0x00010000~0xFFFFFFFF |
+ |
0x03 |
0x00010000~0xFFFFFFFF |
- (9bytes)[-9223372036854775807,-4294967296],[+4294967296,+9223372036854775807]
(因为受限于int64_t,所以不是uint64_t的最大值)
sign |
1byte |
8byte |
- |
0xF4 |
0x0000000100000000~0x7FFFFFFFFFFFFFFF |
+ |
0x04 |
0x0000000100000000~0x7FFFFFFFFFFFFFFF |
string 类型(float类型转为string类型存储)
len_of_string |
string |
int |
string |
array 类型
len_of_array |
element1 |
element2 |
... |
elementn |
int |
e1 |
e2 |
... |
en |
table 类型
按key排序依次存储
tbl = {
a = 1,
b = 2,
c = "tbl",
}
协议模板的C数据结构
struct field {
struct field *next;
struct field_list *child;
char type;
char key[DEFAULT_STR_LEN];
union {
char str_value[DEFAULT_STR_LEN];
int int_value;
} default_value;
};
struct field_list {
struct field *head;
struct field *tail;
int len;
};
// field 用于存储int/float/string,field_list用于存储array/table
代码已经开源了,在这里https://github.com/hanxi/lproto