erlang自定义二进制协议
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

218 行
8.4 KiB

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