erlang自定义二进制协议
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
SisMaker bd9ecb3898 ft: 删除无用代码 il y a 1 an
include ft: 目录结构调整 模块重命名 为后续其他语言做准备 il y a 4 ans
proto ft: 生成erlang还是得要根据msgid 找到msgname il y a 1 an
src ft: 完善一下 il y a 1 an
test ft: 删除无用代码 il y a 1 an
.gitignore ft: 目录结构调整 模块重命名 为后续其他语言做准备 il y a 4 ans
LICENSE Initial commit il y a 5 ans
README.md ft: 完善一下 il y a 1 an
rebar.config ft: 生成erlang还是得要根据msgid 找到msgname il y a 1 an

README.md

genProto

用于根据自定义的协议文件生成 erl, c#, lua的序列化和反序列化代码

Build

rebar3 escriptize  

Use

rebar3 escriptize生成的genProto genPtoto.cmd 在_build/default/bin下面 将其复制到可以被搜索的执行路径或者工作目录
genProto ProtoInputDir Lang("erl", "lua", "cs") OutDir(erl 存在两个输出目录 头文件和Erl文件的输出目录 lua和cs只有一个输入目录)
eg: genProto:convertDir(["./proto", "erl", "./test/erl/", "./test/erl/", "lua", "./test/lua/", "cs", "./test/cs/"]).

简单描述

可用于erlang游戏或者erlang其他网络应用的协议解析编码解码的项目,具有较高的编码解码性能,
协议文件存放在proto目录 文件名为 Message protocol definition file的缩写 mpdf。

支持的数据类型

erl: int8 uint8 int16 uint16 int32 uint32 int64 uint64 integer number(整数或者浮点数) string float(32位浮点数) double(64位浮点数) bool record(struct) 以及上面类型的列表
lua: int8 uint8 int16 uint16 int32 uint32 int64 uint64 integer number(整数或者浮点数) string float(32位浮点数) double(64位浮点数) bool record 以及上面类型的列表
c#: int8 uint8 int16 uint16 int32 uint32 int64 uint64 string float(32位浮点数) double(64位浮点数) bool record 以及上面类型的列表

各种数据类型的编码格式(字节序大端存储, string用utf8编码)

int8:               直接存8bit的值       
uint8:              直接存8bit的值  
int16:              直接存16bit的值
uint16:             直接存16bit的值
int32:              直接存32bit的值
uint32:             直接存32bit的值
int64:              直接存64bit的值
uint64:             直接存64bit的值
integer:            如果值在int8范围区间: 8bit的Tag 值为8 + 8bit的值; 如果值在int16范围区间: 8bit的Tag 值为16 + 16bit的值; 如果值在int32范围区间: 8bit的Tag 值为32 + 32bit的值; 如果值在int64范围区间: 8bit的Tag 值为64 + 64bit的值;
number:             如果值是整数则:编码规则同 integer类型; 如果是浮点数: 如果值在float32范围区间  8bit的Tag 值为33 + 32bit的值; 如果值在float64范围区间  8bit的Tag 值为65 + 64bit的值;    
string:             16bit的Tag 存放的字符串长度(长度不包含字符串结尾符) + 字符串的内容(内容不包含结字符串尾符号)         
float:               直接存放32bit的值
double:             直接存放64bit的值
bool:               占位8bit 如果为true 则存放的值为1 否则存放的值为0
record(struct):     如果是undefined 或者是空指针 则 8bit Tag 值为0, 否则 8bit的tag 值为1 + record的二进制数据
list_+上面的数据类型的时候: 16bit的tag 用于存放 数组的长度 + 按数组顺序序列化每个元素的值的二进制数据(注意:如果列表类型为record(struct) 每个值序列化的时候并不会加 8bit的tag, 直接存record的二进制数据)

关于消息接收转发解码和发送

erlang通常会将接收到的消息由网关进程转发给其他工作进程, 建议先匹配消息id, 然后转发二进制消息到工作进程,然后由工作进程解码再处理
同时广播消息可先编码成二进制之后再广播, 避免重复编码

erl部分简单性能测评

主要和gpb做简单对比测试
gpb测试相关文件在test/gpb目录下
测试协议:
gpb:
message test {
    required string aa = 1;
 }

message phoneNumber {
    required test number = 1;
    required int32 type  = 2;
}

message person {
    required string name = 1;
    required int32 integer = 2;
    optional string email = 3;
    repeated phoneNumber phone = 4;
}

message addressBook {
    repeated  person person1 = 1;
    repeated  person others = 2;
}

message tint32 {
    required int32 int1 = 1;
    required int32 int2 = 2;
    required int32 int3 = 3;
    required int32 int4 = 4;
    required int32 int5 = 5;
    required int32 int6 = 6;
    required int32 int7 = 7;
    required int32 int8 = 8;
    required int32 int9 = 9;
    required int32 int10 = 10;
}
genProto用的协议:

test {
    string aa;
}

phoneNumber{
    test number;
    int32 type;
}

person{
    string name;
    int32 id;
    string email;
    list[phoneNumber] phone;
}

addressBook {
    list[person] person;
    list[person] other;
}

tint32{
    int32 int1;
    int32 int2;
    int32 int3;
    int32 int4;
    int32 int5;
    int32 int6;
    int32 int7;
    int32 int8;
    int32 int9;
    int32 int10;
}
测试运行三次 每次100万次循环
tint32 gpb-------->>
    tint32 encode:
        > timer:tc(mytest, encode_int32, [1000000]).
        {9625000,ok}
        > timer:tc(mytest, encode_int32, [1000000]).
        {9000000,ok}
        > timer:tc(mytest, encode_int32, [1000000]).
        {9969000,ok}
        
    tin32 decode:
        > timer:tc(mytest, decode_int32, [1000000]).
        {6217994,ok}
        > timer:tc(mytest, decode_int32, [1000000]).
        {6187993,ok}
        > timer:tc(mytest, decode_int32, [1000000]).
        {6265994,ok}
        
    size:
        > BTInt32 = mytest:decode_int32(1).
        <<8,1,16,255,255,255,255,255,255,255,255,255,1,24,128,1,
          32,128,255,255,255,255,255,255,255,255,1,40,128,...>>
        31> byte_size(BTInt32).              
        74
tint32 genProto ------->>
    tint32 encode:
        > timer:tc(test, encode_int32, [1000000]).
        {328999,ok}
        > timer:tc(test, encode_int32, [1000000]).
        {328000,ok}
        > timer:tc(test, encode_int32, [1000000]).
        {344000,ok}
    
    tint32 decode:
        > timer:tc(test, decode_int32, [1000000]).
        {328000,ok}
        > timer:tc(test, decode_int32, [1000000]).
        {328000,ok}
        > timer:tc(test, decode_int32, [1000000]).
        {329000,ok}
        
    size:
        > BTInt32 = test:decode_int32(1).  
        <<0,11,0,0,0,1,255,255,255,255,0,0,0,128,255,255,255,128,
          0,1,0,0,255,255,0,0,125,43,117,...>>
        > byte_size(BTInt32).
        42
===============================================================================
===============================================================================        
addressBook gpb-------->>
    addressBook encode:
        > timer:tc(mytest, encode_addressBook, [1000000]).
        {9108990,ok}
        > timer:tc(mytest, encode_addressBook, [1000000]).
        {8999991,ok}
        > timer:tc(mytest, encode_addressBook, [1000000]).
        {9031991,ok}

    addressBook decode:
        > timer:tc(mytest, decode_addressBook, [1000000]).
        {5702995,ok}
        > timer:tc(mytest, decode_addressBook, [1000000]).
        {5764994,ok}
        > timer:tc(mytest, decode_addressBook, [1000000]).
        {5718995,ok}
    size:
        > BAddr = mytest:decode_addressBook(1).
        <<10,43,10,5,65,108,105,99,101,16,144,78,34,15,10,11,10,9,
          49,50,51,52,53,54,55,56,57,16,1,...>>
        > byte_size(BAddr).                    
        75
addressBook genProto -------->>
    addressBook encode:
        > timer:tc(test, encode_addressBook, [1000000]).
        {4186995,ok}
        > timer:tc(test, encode_addressBook, [1000000]).
        {4202996,ok}
        > timer:tc(test, encode_addressBook, [1000000]).
        {4202996,ok}
    addressBook decode:
        > timer:tc(test, decode_addressBook, [1000000]).
        {2749997,ok}
        > timer:tc(test, decode_addressBook, [1000000]).
        {2812997,ok}
        > timer:tc(test, decode_addressBook, [1000000]).
        {2812997,ok}
    size:
        BAddr = test:decode_addressBook(1).  
        <<0,4,0,2,0,5,65,108,105,99,101,0,0,39,16,0,0,0,2,1,0,9,
          49,50,51,52,53,54,55,...>>
        67> byte_size(BAddr). 
        83