http://blog.csdn.net/gamesofsailing/article/details/38335753?utm_source=tuicool&utm_medium=referral

json数据格式在网络中传输需要的数据比二进制庞大太多,我们可以省去key,外加将数字不需要编码成字符串,直接二进制编码就OK。

pack : 将json压包,unpack解包成json。

  1. var Struct = module.exports = {};
  2. Struct.TYPE = {
  3. int8:1,
  4. int16:2,
  5. int32:3,
  6. uint8:4,
  7. uint16:5,
  8. uint32:7,
  9. string:8,
  10. object:9,
  11. aint8:10,
  12. aint16:11,
  13. aint32:12,
  14. auint8:13,
  15. auint16:14,
  16. auint32:15,
  17. aobject:16
  18. };
  19. //
  20. Struct.unpack = function(proto, buf) {
  21. var _unpack = function(proto, buf, pos) {
  22. var p = {};
  23. var ret;
  24. var length;
  25. for (var k in proto) {
  26. var type = proto[k][0];
  27. if (typeof type == 'object') {
  28. var json = type;
  29. type = 'object';
  30. }
  31. if (proto[k].length == 2 && proto[k][1] == 'array') {
  32. type = 'a' + type;
  33. }
  34. var value = [];
  35. switch(Struct.TYPE[type]) {
  36. case Struct.TYPE.int8:
  37. p[k] = buf.readInt8(pos);
  38. pos += 1;
  39. break;
  40. case Struct.TYPE.int16:
  41. p[k] = buf.readInt16BE(pos);
  42. pos += 2;
  43. break;
  44. case Struct.TYPE.int32:
  45. p[k] = buf.readInt32BE(pos);
  46. pos += 4;
  47. break;
  48. case Struct.TYPE.uint8:
  49. p[k] = buf.readUInt8(pos);
  50. pos += 1;
  51. break;
  52. case Struct.TYPE.uint16:
  53. p[k] = buf.readUInt16BE(pos);
  54. pos += 2;
  55. break;
  56. case Struct.TYPE.uint32:
  57. p[k] = buf.readUInt32BE(pos);
  58. pos += 4;
  59. break;
  60. case Struct.TYPE.string:
  61. ret = getLen(buf,pos);
  62. pos = ret[1];
  63. p[k] = buf.toString('utf-8',pos, pos + ret[0]);
  64. pos += ret[0];
  65. break;
  66. case Struct.TYPE.object:
  67. ret = _unpack(json, buf, pos);
  68. p[k] = ret[0];
  69. pos = ret[1];
  70. break;
  71. case Struct.TYPE.aint8:
  72. ret = getLen(buf,pos);
  73. length = ret[0];
  74. pos = ret[1];
  75. for (var i=0; i < length; i++) {
  76. value.push(buf.readInt8(pos));
  77. pos += 1;
  78. }
  79. p[k] = value;
  80. break;
  81. case Struct.TYPE.aint16:
  82. ret = getLen(buf,pos);
  83. length = ret[0];
  84. pos = ret[1];
  85. for (var i=0; i < length; i++) {
  86. value.push(buf.readInt16BE(pos));
  87. pos += 2;
  88. }
  89. p[k] = value;
  90. break;
  91. case Struct.TYPE.aint32:
  92. ret = getLen(buf,pos);
  93. length = ret[0];
  94. pos = ret[1];
  95. for (var i=0; i < length; i++) {
  96. value.push(buf.readInt32BE(pos));
  97. pos += 4;
  98. }
  99. p[k] = value;
  100. break;
  101. case Struct.TYPE.auint8:
  102. ret = getLen(buf,pos);
  103. length = ret[0];
  104. pos = ret[1];
  105. for (var i=0; i < length; i++) {
  106. value.push(buf.readUInt8(pos));
  107. pos += 1;
  108. }
  109. p[k] = value;
  110. break;
  111. case Struct.TYPE.auint16:
  112. ret = getLen(buf,pos);
  113. length = ret[0];
  114. pos = ret[1];
  115. for (var i=0; i < length; i++) {
  116. value.push(buf.readUInt16BE(pos));
  117. pos += 2;
  118. }
  119. p[k] = value;
  120. break;
  121. case Struct.TYPE.auint32:
  122. ret = getLen(buf,pos);
  123. length = ret[0];
  124. pos = ret[1];
  125. for (var i=0; i < length; i++) {
  126. value.push(buf.readUInt32BE(pos));
  127. pos += 4;
  128. }
  129. p[k] = value;
  130. break;
  131. case Struct.TYPE.astring:
  132. ret = getLen(buf,pos);
  133. length = ret[0];
  134. pos = ret[1];
  135. for (var i=0; i < length; i++) {
  136. ret = getLen(buf,pos);
  137. pos = ret[1];
  138. value.push(buf.toString('utf-8',pos, pos + ret[0]));
  139. pos += ret[0];
  140. }
  141. p[k] = value;
  142. break;
  143. case Struct.TYPE.aobject:
  144. ret = getLen(buf,pos);
  145. length = ret[0];
  146. pos = ret[1];
  147. for (var i=0; i < length; i++) {
  148. ret = _unpack(json, buf, pos);
  149. pos = ret[1];
  150. value.push(ret[0]);
  151. }
  152. p[k] = value;
  153. break;
  154. }
  155. }
  156. return [p,pos];
  157. }
  158. return _unpack(proto, buf, 0)[0];
  159. }
  160. Struct.pack = function(proto, msg) {
  161. function _pack(proto, msg, buf, pos) {
  162. for (var k in proto) {
  163. var type = proto[k][0];
  164. if (typeof type == 'object') {
  165. var json = type;
  166. type = 'object';
  167. }
  168. if (proto[k].length == 2 && proto[k][1] == 'array') {
  169. type = 'a' + type;
  170. }
  171. switch(Struct.TYPE[type]) {
  172. case Struct.TYPE.int8:
  173. buf.writeInt8(msg[k], pos);
  174. pos += 1;
  175. break;
  176. case Struct.TYPE.int16:
  177. buf.writeInt16BE(msg[k], pos);
  178. pos += 2;
  179. break;
  180. case Struct.TYPE.int32:
  181. buf.writeInt32BE(msg[k],pos);
  182. pos += 4;
  183. break;
  184. case Struct.TYPE.uint8:
  185. buf.writeUInt8(msg[k], pos);
  186. pos += 1;
  187. break;
  188. case Struct.TYPE.uint16:
  189. buf.writeUInt16BE(msg[k],pos);
  190. pos += 2;
  191. break;
  192. case Struct.TYPE.uint32:
  193. buf.writeUInt32BE(msg[k], pos);
  194. pos += 4;
  195. break;
  196. case Struct.TYPE.string:
  197. pos = setLen(buf, msg[k].length, pos);
  198. buf.write(msg[k],pos);
  199. pos += msg[k].length;
  200. break;
  201. case Struct.TYPE.object:
  202. pos = _pack(json, msg[k], buf, pos);
  203. break;
  204. case Struct.TYPE.aint8:
  205. var list = msg[k];
  206. pos = setLen(buf, list.length, pos);
  207. for (var i=0; i < list.length; i++) {
  208. buf.writeInt8(list[i], pos++);
  209. }
  210. break;
  211. case Struct.TYPE.aint16:
  212. var list = msg[k];
  213. pos = setLen(buf, list.length, pos);
  214. for (var i=0; i < list.length; i++) {
  215. buf.writeInt16BE(list[i], pos);
  216. pos += 2;
  217. }
  218. break;
  219. case Struct.TYPE.aint32:
  220. var list = msg[k];
  221. pos = setLen(buf, list.length, pos);
  222. for (var i=0; i < list.length; i++) {
  223. buf.writeInt32BE(list[i], pos);
  224. pos += 4;
  225. }
  226. break;
  227. case Struct.TYPE.auint8:
  228. var list = msg[k];
  229. pos = setLen(buf, list.length, pos);
  230. for (var i=0; i < list.length; i++) {
  231. buf.writeUInt8(list[i], pos++);
  232. }
  233. break;
  234. case Struct.TYPE.auint16:
  235. var list = msg[k];
  236. pos = setLen(buf, list.length, pos);
  237. for (var i=0; i < list.length; i++) {
  238. buf.writeUInt16BE(list[i], pos);
  239. pos += 2;
  240. }
  241. break;
  242. case Struct.TYPE.auint32:
  243. var list = msg[k];
  244. pos = setLen(buf, list.length, pos);
  245. for (var i=0; i < list.length; i++) {
  246. buf.writeUInt32BE(list[i], pos);
  247. pos +=4;
  248. }
  249. break;
  250. case Struct.TYPE.astring:
  251. var list = msg[k];
  252. pos = setLen(buf, list.length, pos);
  253. for (var i=0; i < list.length; i++) {
  254. pos = setLen(buf, list[i].length,pos);
  255. buf.write(list[i],pos);
  256. pos += list[i].length;
  257. }
  258. break;
  259. case Struct.TYPE.aobject:
  260. var list = msg[k];
  261. pos = setLen(buf, list.length, pos);
  262. for (var i=0; i < list.length; i++) {
  263. pos = _pack(json, list[i], buf, pos);
  264. }
  265. break;
  266. }
  267. //console.log('key: ' + k);
  268. //console.log('pos: ' + pos);
  269. }
  270. return pos;
  271. }
  272. var length = jsonSize(proto, msg);
  273. var buf = new Buffer(length);
  274. _pack(proto, msg, buf, 0);
  275. return buf;
  276. };
  277. var jsonSize = function(proto, msg) {
  278. function _size(proto, msg) {
  279. var size = 0;
  280. var buf = new Buffer(4);
  281. for (var k in proto) {
  282. var type = proto[k][0];
  283. if (typeof type == 'object') {
  284. var json = type;
  285. type = 'object';
  286. }
  287. if (proto[k].length == 2 && proto[k][1] == 'array') {
  288. type = 'a' + type;
  289. }
  290. switch(Struct.TYPE[type]) {
  291. case Struct.TYPE.int8:
  292. size += 1;
  293. break;
  294. case Struct.TYPE.int16:
  295. size += 2;
  296. break;
  297. case Struct.TYPE.int32:
  298. size += 4;
  299. break;
  300. case Struct.TYPE.uint8:
  301. size += 1;
  302. break;
  303. case Struct.TYPE.uint16:
  304. size += 2;
  305. break;
  306. case Struct.TYPE.uint32:
  307. size += 4;
  308. break;
  309. case Struct.TYPE.string:
  310. size += setLen(buf, msg[k].length, 0);
  311. size += msg[k].length;
  312. break;
  313. case Struct.TYPE.object:
  314. size += _size(json, msg[k]);
  315. break;
  316. case Struct.TYPE.aint8:
  317. var list = msg[k];
  318. size += setLen(buf, list.length, 0);
  319. size += list.length;
  320. break;
  321. case Struct.TYPE.aint16:
  322. var list = msg[k];
  323. size += setLen(buf, list.length, 0);
  324. size += list.length * 2;
  325. break;
  326. case Struct.TYPE.aint32:
  327. var list = msg[k];
  328. size += setLen(buf, list.length, 0);
  329. size += list.length * 4;
  330. break;
  331. case Struct.TYPE.auint8:
  332. var list = msg[k];
  333. size += setLen(buf, list.length, 0);
  334. size += list.length;
  335. break;
  336. case Struct.TYPE.auint16:
  337. var list = msg[k];
  338. size += setLen(buf, list.length, 0);
  339. size += list.length * 2;
  340. break;
  341. case Struct.TYPE.auint32:
  342. var list = msg[k];
  343. size += setLen(buf, list.length, 0);
  344. size += list.length * 4;
  345. break;
  346. case Struct.TYPE.astring:
  347. var list = msg[k];
  348. size += setLen(buf, list.length, 0);
  349. for (var i=0; i < list.length; i++) {
  350. size += setLen(buf, list[i].length,0);
  351. size += list[i].length;
  352. }
  353. break;
  354. case Struct.TYPE.aobject:
  355. var list = msg[k];
  356. size += setLen(buf, list.length, 0);
  357. for (var i=0; i < list.length; i++) {
  358. size += _size(json, list[i]);
  359. }
  360. break;
  361. }
  362. }
  363. return size;
  364. }
  365. var size = 0;
  366. size += _size(proto, msg);
  367. return size;
  368. }
  369. var MASK_7 = (1<<7) - 1;
  370. var MASK_8 = (1<<8) - 1;
  371. var MAX_LEN = (1<<28);
  372. //不定长记录长度,1-4个字节,和MQTT表示长度的方法相同
  373. var getLen = function(buf, pos) {
  374. var len = 0;
  375. for (var i = 0; i < 4; i++) {
  376. var value = buf.readUInt8(pos);
  377. //console.log('get: ' + value);
  378. len += (value & MASK_7) << (7 * i);
  379. pos += 1;
  380. if (value < 127) {
  381. break;
  382. }
  383. }
  384. return [len, pos];
  385. }
  386. var setLen = function(buf, len, pos) {
  387. while(len > 0) {
  388. var value = len & MASK_8;
  389. len = len >> 7;
  390. if (len > 0) {
  391. value = value | 128;
  392. }
  393. buf.writeUInt8(value, pos++);
  394. }
  395. return pos;
  396. }

测试代码:

  1. var Struct = require('./struct');
  2. var proto = {
  3. int8   : ['int8'],
  4. int16  : ['int16'],
  5. int32  : ['int32'],
  6. uint8  : ['uint8'],
  7. uint16 : ['uint16'],
  8. uint32 : ['uint32'],
  9. string : ['string'],
  10. aint8  : ['int8', 'array'],
  11. aint16 : ['int16', 'array'],
  12. aint32 : ['int32', 'array'],
  13. auint8 : ['uint8', 'array'],
  14. auint16: ['uint16', 'array'],
  15. auint32: ['uint32', 'array'],
  16. object : [
  17. {int8: ['int8'], int16: ['int16'], string: ['string'], astring: ['astring']}
  18. ],
  19. aobject : [
  20. {int8: ['int8'], int16: ['int16'], string: ['string'], astring: ['astring']},
  21. 'array'
  22. ],
  23. astring: ['string', 'array']
  24. }
  25. var msg = {
  26. int8   : 12,
  27. int16  : 1234,
  28. int32  : 12345,
  29. uint8  : 130,// > 128
  30. uint16 : 32800, // >> 128 * 256
  31. uint32 : 3221245472, // >> 3 * (1<<30)
  32. string : 'hello world',
  33. aint8  : [-1, -2, -3, -5, -6],
  34. aint16 : [-11, -12, -13, -15, -17],
  35. aint32 : [-337, -338, -339, -3310, -3311],
  36. auint8 : [1, 2, 3, 4],
  37. auint16: [8, 9, 10, 11, 12],
  38. auint32: [12, 13, 15, 16],
  39. object : {int8: 12, int16: 1234, string: 'somebady', astring: ['save me', 'Dont stop me now']},
  40. aobject : [{int8: 12, int16: 1234, string: 'somebady', astring: ['save me', 'Dont stop me now']}, {int8: 12, int16: 1234, string: 'somebady', astring: ['save me', 'Dont stop me now']}],
  41. astring: ['melo', 'kaka', 'much', 'save']
  42. }
  43. var buf = Struct.pack(proto, msg);
  44. console.log(buf);
  45. var remsg = Struct.unpack(proto, buf);
  46. console.log(JSON.stringify(remsg));

【转】参照protobuf,将json数据转换成二进制在网络中传输。的更多相关文章

  1. 【转】C#中将JSon数据转换成实体类,将实体类转换成Json

    http://wo13145219.iteye.com/blog/2022667 http://json2csharp.chahuo.com/ using System; using System.C ...

  2. 利用JAVA反射机制将JSON数据转换成JAVA对象

    net.sf.json.JSONObject为我们提供了toBean方法用来转换为JAVA对象, 功能更为强大,  这里借鉴采用JDK的反射机制, 作为简单的辅助工具使用,   有些数据类型需要进行转 ...

  3. 将JSON数据转换成JAVA的实体类

    思路:首先将JSON格式的数据转换成JSONObject,然后将JSONObject转换成Java的实体类(其中类属性包括List等类型) Java实体类: SearchFilter 类 1 publ ...

  4. 把HDFS里的json数据转换成csv格式

      1. 全景图 2. 用ListHDFS获取所有文件名   如果想重新再取一次,右健view state:   点击 clear state, 再运行,即可再次采集数据了.   3. 用FetchH ...

  5. 把json数据转换成集合

    Sting MessageList="";JSONArray json = JSONArray.fromObject(MessageList);JSONObject object ...

  6. 4.使用Jackson将Json数据转换成实体数据

    Jar下载地址:http://jackson.codehaus.org/ 注意: 一.类中的属性名称一定要和Json数据的属性名称一致(大写和小写敏感),类之间的嵌套关系也应该和Json数据的嵌套关系 ...

  7. JSON数据转换成table表格

    <%@ page contentType="text/html; charset=UTF-8" %> <%@taglib uri="/struts-ta ...

  8. json数据转换成结构体

    package main import ( "encoding/json" "fmt" ) type IT1 struct { Company string ` ...

  9. Java中将JSON格式的数据转换成对应的Bean、Map、List数据

    简单说明: 为了方便数据在客户端及服务器端的传输,有时候我们会用一些比较方便组织的数据类型,比如json.xml等传给客户端,客户端也可以重新组织数据传回服务器端.JSON和XML提供了一套比较方便的 ...

随机推荐

  1. Python之查询最新的文件

    import os # 定义文件的目录 result_dir = r'E:\python\测试报告' lists = os.listdir(result_dir) # 重新按时间对目录下的文件进行排序 ...

  2. Python之邮件发送

    Python的smtplib提供了一种很方便的途径用来发送电子邮件,它有SMTP协议进行简单的封装,可以使用SMTP对象的sendmail方法发送邮件,通过help()查看SMTP所提供的方法如下: ...

  3. 洛谷 P1903 【模板】分块/带修改莫队(数颜色)

    题目描述 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔. 2 ...

  4. RYU的GUI安装

    1. RYU安装 Ubuntu14.04 LTS 1.sudo apt-get install git python-pip libxml2-dev libxslt1-dev python2.7-de ...

  5. uva297 Quadtrees (线段树思想,区间操作)

    借鉴了线段数区间操作的思想,只是把一个结点的孩子扩展到了4个, 结点k,四个孩子编号分别为4*k+1,4*k+2,4*k+3,4*K+4,从零开始. 根据层数,确定权值. #include<cs ...

  6. 标签中的name属性和ID属性的区别

    标签中的name属性和ID属性的区别 2018年05月13日 10:17:44 tssit 阅读数:760   编程这么久,细想了一下,发现这个问题还不是很清楚,汗!看了几篇文章,整理了一下,分享下! ...

  7. Bootstrap 徽章(Badges)

    本章将讲解Bootstrap徽章(Badges),徽章与标签相似,主要的区别是徽章的圆角比较圆滑. 徽章(Badges)主要用于突出显示新的或未读的项,如果使用徽章,只需要把<span clas ...

  8. HTML5语义

    语义通俗化为意义,也就是语义化的元素等于意义化的元素,看到这个元素的名称,就知道这个元素的意义,是拿来做什么用的,这就是HTML5的一个新特性,一个具有语义化的元素能够清楚的把元素的意义告诉浏览器和开 ...

  9. ES6 -- 模板字符串(反单引号)

    1)直接使用变量 // before var str = 'test'; console.log(str + "123"); // now var str = 'test'; co ...

  10. PostgreSQL学习(2)-- mvcc

    1.PG事务隔离级别 在数据库中,并发的操作进行读写数据时,则会遇到脏读.不可重复读.幻读.串行化异常等问题. 数据库事务的特性: 原子性(Atomicity):事务作为一个整体被执行,包含在其中的对 ...