erlang自定义二进制协议
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

220 rader
8.4 KiB

5 år sedan
5 år sedan
5 år sedan
  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 用于存放 数组的长度 + 按数组顺序序列化每个元素的值的二进制数据
  35. ### maybe TODO
  36. 生成的protoMsg.erl
  37. encode 函数参数列表太长时 换行显示
  38. encode返回的编码列表参数太多时 换行显示
  39. decodeBin simple类型解码列表过长时 换行显示
  40. decodeBin 返回元组元素太多时 换行显示
  41. ### 关于消息接收转发解码和发送
  42. erlang通常会将接收到的消息由网关进程转发给其他工作进程, 建议先匹配消息id, 然后转发二进制消息到工作进程,然后由工作进程解码再处理
  43. 同时广播消息可先编码成二进制之后再广播, 避免重复编码
  44. ### erl部分简单性能测评
  45. 主要和gpb做简单对比测试
  46. gpb测试相关文件在test/gpb目录下
  47. 测试协议:
  48. gpb:
  49. message test {
  50. required string aa = 1;
  51. }
  52. message phoneNumber {
  53. required test number = 1;
  54. required int32 type = 2;
  55. }
  56. message person {
  57. required string name = 1;
  58. required int32 integer = 2;
  59. optional string email = 3;
  60. repeated phoneNumber phone = 4;
  61. }
  62. message addressBook {
  63. repeated person person1 = 1;
  64. repeated person others = 2;
  65. }
  66. message tint32 {
  67. required int32 int1 = 1;
  68. required int32 int2 = 2;
  69. required int32 int3 = 3;
  70. required int32 int4 = 4;
  71. required int32 int5 = 5;
  72. required int32 int6 = 6;
  73. required int32 int7 = 7;
  74. required int32 int8 = 8;
  75. required int32 int9 = 9;
  76. required int32 int10 = 10;
  77. }
  78. genProto用的协议:
  79. test {
  80. string aa;
  81. }
  82. phoneNumber{
  83. test number;
  84. int32 type;
  85. }
  86. person{
  87. string name;
  88. int32 id;
  89. string email;
  90. list[phoneNumber] phone;
  91. }
  92. addressBook {
  93. list[person] person;
  94. list[person] other;
  95. }
  96. tint32{
  97. int32 int1;
  98. int32 int2;
  99. int32 int3;
  100. int32 int4;
  101. int32 int5;
  102. int32 int6;
  103. int32 int7;
  104. int32 int8;
  105. int32 int9;
  106. int32 int10;
  107. }
  108. 测试运行三次 每次100万次循环
  109. tint32 gpb-------->>
  110. tint32 encode:
  111. > timer:tc(mytest, encode_int32, [1000000]).
  112. {9625000,ok}
  113. > timer:tc(mytest, encode_int32, [1000000]).
  114. {9000000,ok}
  115. > timer:tc(mytest, encode_int32, [1000000]).
  116. {9969000,ok}
  117. tin32 decode:
  118. > timer:tc(mytest, decode_int32, [1000000]).
  119. {6217994,ok}
  120. > timer:tc(mytest, decode_int32, [1000000]).
  121. {6187993,ok}
  122. > timer:tc(mytest, decode_int32, [1000000]).
  123. {6265994,ok}
  124. size:
  125. > BTInt32 = mytest:decode_int32(1).
  126. <<8,1,16,255,255,255,255,255,255,255,255,255,1,24,128,1,
  127. 32,128,255,255,255,255,255,255,255,255,1,40,128,...>>
  128. 31> byte_size(BTInt32).
  129. 74
  130. tint32 genProto ------->>
  131. tint32 encode:
  132. > timer:tc(test, encode_int32, [1000000]).
  133. {328999,ok}
  134. > timer:tc(test, encode_int32, [1000000]).
  135. {328000,ok}
  136. > timer:tc(test, encode_int32, [1000000]).
  137. {344000,ok}
  138. tint32 decode:
  139. > timer:tc(test, decode_int32, [1000000]).
  140. {328000,ok}
  141. > timer:tc(test, decode_int32, [1000000]).
  142. {328000,ok}
  143. > timer:tc(test, decode_int32, [1000000]).
  144. {329000,ok}
  145. size:
  146. > BTInt32 = test:decode_int32(1).
  147. <<0,11,0,0,0,1,255,255,255,255,0,0,0,128,255,255,255,128,
  148. 0,1,0,0,255,255,0,0,125,43,117,...>>
  149. > byte_size(BTInt32).
  150. 42
  151. ===============================================================================
  152. ===============================================================================
  153. addressBook gpb-------->>
  154. addressBook encode:
  155. > timer:tc(mytest, encode_addressBook, [1000000]).
  156. {9108990,ok}
  157. > timer:tc(mytest, encode_addressBook, [1000000]).
  158. {8999991,ok}
  159. > timer:tc(mytest, encode_addressBook, [1000000]).
  160. {9031991,ok}
  161. addressBook decode:
  162. > timer:tc(mytest, decode_addressBook, [1000000]).
  163. {5702995,ok}
  164. > timer:tc(mytest, decode_addressBook, [1000000]).
  165. {5764994,ok}
  166. > timer:tc(mytest, decode_addressBook, [1000000]).
  167. {5718995,ok}
  168. size:
  169. > BAddr = mytest:decode_addressBook(1).
  170. <<10,43,10,5,65,108,105,99,101,16,144,78,34,15,10,11,10,9,
  171. 49,50,51,52,53,54,55,56,57,16,1,...>>
  172. > byte_size(BAddr).
  173. 75
  174. addressBook genProto -------->>
  175. addressBook encode:
  176. > timer:tc(test, encode_addressBook, [1000000]).
  177. {4186995,ok}
  178. > timer:tc(test, encode_addressBook, [1000000]).
  179. {4202996,ok}
  180. > timer:tc(test, encode_addressBook, [1000000]).
  181. {4202996,ok}
  182. addressBook decode:
  183. > timer:tc(test, decode_addressBook, [1000000]).
  184. {2749997,ok}
  185. > timer:tc(test, decode_addressBook, [1000000]).
  186. {2812997,ok}
  187. > timer:tc(test, decode_addressBook, [1000000]).
  188. {2812997,ok}
  189. size:
  190. BAddr = test:decode_addressBook(1).
  191. <<0,4,0,2,0,5,65,108,105,99,101,0,0,39,16,0,0,0,2,1,0,9,
  192. 49,50,51,52,53,54,55,...>>
  193. 67> byte_size(BAddr).
  194. 83