erlang自定义二进制协议
No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

224 líneas
8.3 KiB

hace 4 años
hace 5 años
hace 5 años
hace 5 años
hace 5 años
  1. genProto
  2. =====
  3. 用于根据自定义的协议文件生成 erl, c#, lua的序列化和反序列化代码
  4. Build
  5. -----
  6. rebar3 escriptize
  7. Use
  8. -----
  9. rebar3 escriptize生成的genProto genPtoto.cmd 在_build/default/bin下面 将其复制到可以被搜索的执行路径或者工作目录
  10. genProto ProtoInputDir HrlOutDir ErlOutDir
  11. # 简单描述
  12. 可用于erlang游戏或者erlang其他网络应用的协议解析编码解码的项目,具有较高的编码解码性能,
  13. 协议文件存放在proto目录 文件名为 Message protocol definition file的缩写 mpdf。
  14. # 支持的数据类型
  15. erl: int8 uint8 int16 uint16 int32 uint32 int64 uint64 integer(整数 64位) number(整数或者浮点数 64位) string float(32位浮点数) double(64位浮点数) bool record(struct) 以及上面类型的列表
  16. lua(待修正): int8 uint8 int16 uint16 int32 uint32 int64 uint64 integer(整数 64位) number(整数或者浮点数 64位) string float(32位浮点数) double(64位浮点数) bool record 以及上面类型的列表
  17. c#(待修正): int8 uint8 int16 uint16 int32 uint32 int64 uint64 integer(整数 64位) number(整数或者浮点数 64位) string float(32位浮点数) double(64位浮点数) bool record 以及上面类型的列表
  18. # 各种数据类型的编码格式(字节序大端存储, string用utf8编码)
  19. int8: 直接存8bit的值
  20. uint8: 直接存8bit的值
  21. int16: 直接存16bit的值
  22. uint16: 直接存16bit的值
  23. int32: 直接存32bit的值
  24. uint32: 直接存32bit的值
  25. int64: 直接存64bit的值
  26. uint64: 直接存64bit的值
  27. integer: 如果值在int8范围区间: 8bit的Tag 值为8 + 8bit的值; 如果值在int16范围区间: 8bit的Tag 值为16 + 16bit的值; 如果值在int32范围区间: 8bit的Tag 值为32 + 32bit的值; 如果值在int64范围区间: 8bit的Tag 值为64 + 64bit的值;
  28. number: 如果值是整数则:编码规则同 integer类型; 如果是浮点数: 如果值在float32范围区间 8bit的Tag 值为33 + 32bit的值; 如果值在float64范围区间 8bit的Tag 值为65 + 64bit的值;
  29. string: 16bit的Tag 存放的字符串长度(长度不包含字符串结尾符) + 字符串的内容(内容不包含结字符串尾符号)
  30. float: 直接存放32bit的值
  31. double: 直接存放64bit的值
  32. bool: 占位8bit 如果为true 则存放的值为1 否则存放的值为0
  33. record(struct): 如果是undefined 或者是空指针 则 8bit Tag 值为0, 否则 8bit的tag 值为1 + record的二进制数据
  34. list_+上面的数据类型的时候: 16bit的tag 用于存放 数组的长度 + 按数组顺序序列化每个元素的值的二进制数据(注意:如果列表类型为record(struct) 每个值序列化的时候并不会加 8bit的tag, 直接存record的二进制数据)
  35. ### maybe TODO
  36. lua 支持 integer number
  37. ### 关于消息接收转发解码和发送
  38. erlang通常会将接收到的消息由网关进程转发给其他工作进程, 建议先匹配消息id, 然后转发二进制消息到工作进程,然后由工作进程解码再处理
  39. 同时广播消息可先编码成二进制之后再广播, 避免重复编码
  40. ### erl部分简单性能测评
  41. 主要和gpb做简单对比测试
  42. gpb测试相关文件在test/gpb目录下
  43. 测试协议:
  44. gpb:
  45. message test {
  46. required string aa = 1;
  47. }
  48. message phoneNumber {
  49. required test number = 1;
  50. required int32 type = 2;
  51. }
  52. message person {
  53. required string name = 1;
  54. required int32 integer = 2;
  55. optional string email = 3;
  56. repeated phoneNumber phone = 4;
  57. }
  58. message addressBook {
  59. repeated person person1 = 1;
  60. repeated person others = 2;
  61. }
  62. message tint32 {
  63. required int32 int1 = 1;
  64. required int32 int2 = 2;
  65. required int32 int3 = 3;
  66. required int32 int4 = 4;
  67. required int32 int5 = 5;
  68. required int32 int6 = 6;
  69. required int32 int7 = 7;
  70. required int32 int8 = 8;
  71. required int32 int9 = 9;
  72. required int32 int10 = 10;
  73. }
  74. genProto用的协议:
  75. test {
  76. string aa;
  77. }
  78. phoneNumber{
  79. test number;
  80. int32 type;
  81. }
  82. person{
  83. string name;
  84. int32 id;
  85. string email;
  86. list[phoneNumber] phone;
  87. }
  88. addressBook {
  89. list[person] person;
  90. list[person] other;
  91. }
  92. tint32{
  93. int32 int1;
  94. int32 int2;
  95. int32 int3;
  96. int32 int4;
  97. int32 int5;
  98. int32 int6;
  99. int32 int7;
  100. int32 int8;
  101. int32 int9;
  102. int32 int10;
  103. }
  104. 测试运行三次 每次100万次循环
  105. tint32 gpb-------->>
  106. tint32 encode:
  107. > timer:tc(mytest, encode_int32, [1000000]).
  108. {9625000,ok}
  109. > timer:tc(mytest, encode_int32, [1000000]).
  110. {9000000,ok}
  111. > timer:tc(mytest, encode_int32, [1000000]).
  112. {9969000,ok}
  113. tin32 decode:
  114. > timer:tc(mytest, decode_int32, [1000000]).
  115. {6217994,ok}
  116. > timer:tc(mytest, decode_int32, [1000000]).
  117. {6187993,ok}
  118. > timer:tc(mytest, decode_int32, [1000000]).
  119. {6265994,ok}
  120. size:
  121. > BTInt32 = mytest:decode_int32(1).
  122. <<8,1,16,255,255,255,255,255,255,255,255,255,1,24,128,1,
  123. 32,128,255,255,255,255,255,255,255,255,1,40,128,...>>
  124. 31> byte_size(BTInt32).
  125. 74
  126. tint32 genProto ------->>
  127. tint32 encode:
  128. > timer:tc(test, encode_int32, [1000000]).
  129. {328999,ok}
  130. > timer:tc(test, encode_int32, [1000000]).
  131. {328000,ok}
  132. > timer:tc(test, encode_int32, [1000000]).
  133. {344000,ok}
  134. tint32 decode:
  135. > timer:tc(test, decode_int32, [1000000]).
  136. {328000,ok}
  137. > timer:tc(test, decode_int32, [1000000]).
  138. {328000,ok}
  139. > timer:tc(test, decode_int32, [1000000]).
  140. {329000,ok}
  141. size:
  142. > BTInt32 = test:decode_int32(1).
  143. <<0,11,0,0,0,1,255,255,255,255,0,0,0,128,255,255,255,128,
  144. 0,1,0,0,255,255,0,0,125,43,117,...>>
  145. > byte_size(BTInt32).
  146. 42
  147. ===============================================================================
  148. ===============================================================================
  149. addressBook gpb-------->>
  150. addressBook encode:
  151. > timer:tc(mytest, encode_addressBook, [1000000]).
  152. {9108990,ok}
  153. > timer:tc(mytest, encode_addressBook, [1000000]).
  154. {8999991,ok}
  155. > timer:tc(mytest, encode_addressBook, [1000000]).
  156. {9031991,ok}
  157. addressBook decode:
  158. > timer:tc(mytest, decode_addressBook, [1000000]).
  159. {5702995,ok}
  160. > timer:tc(mytest, decode_addressBook, [1000000]).
  161. {5764994,ok}
  162. > timer:tc(mytest, decode_addressBook, [1000000]).
  163. {5718995,ok}
  164. size:
  165. > BAddr = mytest:decode_addressBook(1).
  166. <<10,43,10,5,65,108,105,99,101,16,144,78,34,15,10,11,10,9,
  167. 49,50,51,52,53,54,55,56,57,16,1,...>>
  168. > byte_size(BAddr).
  169. 75
  170. addressBook genProto -------->>
  171. addressBook encode:
  172. > timer:tc(test, encode_addressBook, [1000000]).
  173. {4186995,ok}
  174. > timer:tc(test, encode_addressBook, [1000000]).
  175. {4202996,ok}
  176. > timer:tc(test, encode_addressBook, [1000000]).
  177. {4202996,ok}
  178. addressBook decode:
  179. > timer:tc(test, decode_addressBook, [1000000]).
  180. {2749997,ok}
  181. > timer:tc(test, decode_addressBook, [1000000]).
  182. {2812997,ok}
  183. > timer:tc(test, decode_addressBook, [1000000]).
  184. {2812997,ok}
  185. size:
  186. BAddr = test:decode_addressBook(1).
  187. <<0,4,0,2,0,5,65,108,105,99,101,0,0,39,16,0,0,0,2,1,0,9,
  188. 49,50,51,52,53,54,55,...>>
  189. 67> byte_size(BAddr).
  190. 83