【转】参照protobuf,将json数据转换成二进制在网络中传输。
http://blog.csdn.net/gamesofsailing/article/details/38335753?utm_source=tuicool&utm_medium=referral
json数据格式在网络中传输需要的数据比二进制庞大太多,我们可以省去key,外加将数字不需要编码成字符串,直接二进制编码就OK。
pack : 将json压包,unpack解包成json。
- var Struct = module.exports = {};
- Struct.TYPE = {
- int8:1,
- int16:2,
- int32:3,
- uint8:4,
- uint16:5,
- uint32:7,
- string:8,
- object:9,
- aint8:10,
- aint16:11,
- aint32:12,
- auint8:13,
- auint16:14,
- auint32:15,
- aobject:16
- };
- //
- Struct.unpack = function(proto, buf) {
- var _unpack = function(proto, buf, pos) {
- var p = {};
- var ret;
- var length;
- for (var k in proto) {
- var type = proto[k][0];
- if (typeof type == 'object') {
- var json = type;
- type = 'object';
- }
- if (proto[k].length == 2 && proto[k][1] == 'array') {
- type = 'a' + type;
- }
- var value = [];
- switch(Struct.TYPE[type]) {
- case Struct.TYPE.int8:
- p[k] = buf.readInt8(pos);
- pos += 1;
- break;
- case Struct.TYPE.int16:
- p[k] = buf.readInt16BE(pos);
- pos += 2;
- break;
- case Struct.TYPE.int32:
- p[k] = buf.readInt32BE(pos);
- pos += 4;
- break;
- case Struct.TYPE.uint8:
- p[k] = buf.readUInt8(pos);
- pos += 1;
- break;
- case Struct.TYPE.uint16:
- p[k] = buf.readUInt16BE(pos);
- pos += 2;
- break;
- case Struct.TYPE.uint32:
- p[k] = buf.readUInt32BE(pos);
- pos += 4;
- break;
- case Struct.TYPE.string:
- ret = getLen(buf,pos);
- pos = ret[1];
- p[k] = buf.toString('utf-8',pos, pos + ret[0]);
- pos += ret[0];
- break;
- case Struct.TYPE.object:
- ret = _unpack(json, buf, pos);
- p[k] = ret[0];
- pos = ret[1];
- break;
- case Struct.TYPE.aint8:
- ret = getLen(buf,pos);
- length = ret[0];
- pos = ret[1];
- for (var i=0; i < length; i++) {
- value.push(buf.readInt8(pos));
- pos += 1;
- }
- p[k] = value;
- break;
- case Struct.TYPE.aint16:
- ret = getLen(buf,pos);
- length = ret[0];
- pos = ret[1];
- for (var i=0; i < length; i++) {
- value.push(buf.readInt16BE(pos));
- pos += 2;
- }
- p[k] = value;
- break;
- case Struct.TYPE.aint32:
- ret = getLen(buf,pos);
- length = ret[0];
- pos = ret[1];
- for (var i=0; i < length; i++) {
- value.push(buf.readInt32BE(pos));
- pos += 4;
- }
- p[k] = value;
- break;
- case Struct.TYPE.auint8:
- ret = getLen(buf,pos);
- length = ret[0];
- pos = ret[1];
- for (var i=0; i < length; i++) {
- value.push(buf.readUInt8(pos));
- pos += 1;
- }
- p[k] = value;
- break;
- case Struct.TYPE.auint16:
- ret = getLen(buf,pos);
- length = ret[0];
- pos = ret[1];
- for (var i=0; i < length; i++) {
- value.push(buf.readUInt16BE(pos));
- pos += 2;
- }
- p[k] = value;
- break;
- case Struct.TYPE.auint32:
- ret = getLen(buf,pos);
- length = ret[0];
- pos = ret[1];
- for (var i=0; i < length; i++) {
- value.push(buf.readUInt32BE(pos));
- pos += 4;
- }
- p[k] = value;
- break;
- case Struct.TYPE.astring:
- ret = getLen(buf,pos);
- length = ret[0];
- pos = ret[1];
- for (var i=0; i < length; i++) {
- ret = getLen(buf,pos);
- pos = ret[1];
- value.push(buf.toString('utf-8',pos, pos + ret[0]));
- pos += ret[0];
- }
- p[k] = value;
- break;
- case Struct.TYPE.aobject:
- ret = getLen(buf,pos);
- length = ret[0];
- pos = ret[1];
- for (var i=0; i < length; i++) {
- ret = _unpack(json, buf, pos);
- pos = ret[1];
- value.push(ret[0]);
- }
- p[k] = value;
- break;
- }
- }
- return [p,pos];
- }
- return _unpack(proto, buf, 0)[0];
- }
- Struct.pack = function(proto, msg) {
- function _pack(proto, msg, buf, pos) {
- for (var k in proto) {
- var type = proto[k][0];
- if (typeof type == 'object') {
- var json = type;
- type = 'object';
- }
- if (proto[k].length == 2 && proto[k][1] == 'array') {
- type = 'a' + type;
- }
- switch(Struct.TYPE[type]) {
- case Struct.TYPE.int8:
- buf.writeInt8(msg[k], pos);
- pos += 1;
- break;
- case Struct.TYPE.int16:
- buf.writeInt16BE(msg[k], pos);
- pos += 2;
- break;
- case Struct.TYPE.int32:
- buf.writeInt32BE(msg[k],pos);
- pos += 4;
- break;
- case Struct.TYPE.uint8:
- buf.writeUInt8(msg[k], pos);
- pos += 1;
- break;
- case Struct.TYPE.uint16:
- buf.writeUInt16BE(msg[k],pos);
- pos += 2;
- break;
- case Struct.TYPE.uint32:
- buf.writeUInt32BE(msg[k], pos);
- pos += 4;
- break;
- case Struct.TYPE.string:
- pos = setLen(buf, msg[k].length, pos);
- buf.write(msg[k],pos);
- pos += msg[k].length;
- break;
- case Struct.TYPE.object:
- pos = _pack(json, msg[k], buf, pos);
- break;
- case Struct.TYPE.aint8:
- var list = msg[k];
- pos = setLen(buf, list.length, pos);
- for (var i=0; i < list.length; i++) {
- buf.writeInt8(list[i], pos++);
- }
- break;
- case Struct.TYPE.aint16:
- var list = msg[k];
- pos = setLen(buf, list.length, pos);
- for (var i=0; i < list.length; i++) {
- buf.writeInt16BE(list[i], pos);
- pos += 2;
- }
- break;
- case Struct.TYPE.aint32:
- var list = msg[k];
- pos = setLen(buf, list.length, pos);
- for (var i=0; i < list.length; i++) {
- buf.writeInt32BE(list[i], pos);
- pos += 4;
- }
- break;
- case Struct.TYPE.auint8:
- var list = msg[k];
- pos = setLen(buf, list.length, pos);
- for (var i=0; i < list.length; i++) {
- buf.writeUInt8(list[i], pos++);
- }
- break;
- case Struct.TYPE.auint16:
- var list = msg[k];
- pos = setLen(buf, list.length, pos);
- for (var i=0; i < list.length; i++) {
- buf.writeUInt16BE(list[i], pos);
- pos += 2;
- }
- break;
- case Struct.TYPE.auint32:
- var list = msg[k];
- pos = setLen(buf, list.length, pos);
- for (var i=0; i < list.length; i++) {
- buf.writeUInt32BE(list[i], pos);
- pos +=4;
- }
- break;
- case Struct.TYPE.astring:
- var list = msg[k];
- pos = setLen(buf, list.length, pos);
- for (var i=0; i < list.length; i++) {
- pos = setLen(buf, list[i].length,pos);
- buf.write(list[i],pos);
- pos += list[i].length;
- }
- break;
- case Struct.TYPE.aobject:
- var list = msg[k];
- pos = setLen(buf, list.length, pos);
- for (var i=0; i < list.length; i++) {
- pos = _pack(json, list[i], buf, pos);
- }
- break;
- }
- //console.log('key: ' + k);
- //console.log('pos: ' + pos);
- }
- return pos;
- }
- var length = jsonSize(proto, msg);
- var buf = new Buffer(length);
- _pack(proto, msg, buf, 0);
- return buf;
- };
- var jsonSize = function(proto, msg) {
- function _size(proto, msg) {
- var size = 0;
- var buf = new Buffer(4);
- for (var k in proto) {
- var type = proto[k][0];
- if (typeof type == 'object') {
- var json = type;
- type = 'object';
- }
- if (proto[k].length == 2 && proto[k][1] == 'array') {
- type = 'a' + type;
- }
- switch(Struct.TYPE[type]) {
- case Struct.TYPE.int8:
- size += 1;
- break;
- case Struct.TYPE.int16:
- size += 2;
- break;
- case Struct.TYPE.int32:
- size += 4;
- break;
- case Struct.TYPE.uint8:
- size += 1;
- break;
- case Struct.TYPE.uint16:
- size += 2;
- break;
- case Struct.TYPE.uint32:
- size += 4;
- break;
- case Struct.TYPE.string:
- size += setLen(buf, msg[k].length, 0);
- size += msg[k].length;
- break;
- case Struct.TYPE.object:
- size += _size(json, msg[k]);
- break;
- case Struct.TYPE.aint8:
- var list = msg[k];
- size += setLen(buf, list.length, 0);
- size += list.length;
- break;
- case Struct.TYPE.aint16:
- var list = msg[k];
- size += setLen(buf, list.length, 0);
- size += list.length * 2;
- break;
- case Struct.TYPE.aint32:
- var list = msg[k];
- size += setLen(buf, list.length, 0);
- size += list.length * 4;
- break;
- case Struct.TYPE.auint8:
- var list = msg[k];
- size += setLen(buf, list.length, 0);
- size += list.length;
- break;
- case Struct.TYPE.auint16:
- var list = msg[k];
- size += setLen(buf, list.length, 0);
- size += list.length * 2;
- break;
- case Struct.TYPE.auint32:
- var list = msg[k];
- size += setLen(buf, list.length, 0);
- size += list.length * 4;
- break;
- case Struct.TYPE.astring:
- var list = msg[k];
- size += setLen(buf, list.length, 0);
- for (var i=0; i < list.length; i++) {
- size += setLen(buf, list[i].length,0);
- size += list[i].length;
- }
- break;
- case Struct.TYPE.aobject:
- var list = msg[k];
- size += setLen(buf, list.length, 0);
- for (var i=0; i < list.length; i++) {
- size += _size(json, list[i]);
- }
- break;
- }
- }
- return size;
- }
- var size = 0;
- size += _size(proto, msg);
- return size;
- }
- var MASK_7 = (1<<7) - 1;
- var MASK_8 = (1<<8) - 1;
- var MAX_LEN = (1<<28);
- //不定长记录长度,1-4个字节,和MQTT表示长度的方法相同
- var getLen = function(buf, pos) {
- var len = 0;
- for (var i = 0; i < 4; i++) {
- var value = buf.readUInt8(pos);
- //console.log('get: ' + value);
- len += (value & MASK_7) << (7 * i);
- pos += 1;
- if (value < 127) {
- break;
- }
- }
- return [len, pos];
- }
- var setLen = function(buf, len, pos) {
- while(len > 0) {
- var value = len & MASK_8;
- len = len >> 7;
- if (len > 0) {
- value = value | 128;
- }
- buf.writeUInt8(value, pos++);
- }
- return pos;
- }
测试代码:
- var Struct = require('./struct');
- var proto = {
- int8 : ['int8'],
- int16 : ['int16'],
- int32 : ['int32'],
- uint8 : ['uint8'],
- uint16 : ['uint16'],
- uint32 : ['uint32'],
- string : ['string'],
- aint8 : ['int8', 'array'],
- aint16 : ['int16', 'array'],
- aint32 : ['int32', 'array'],
- auint8 : ['uint8', 'array'],
- auint16: ['uint16', 'array'],
- auint32: ['uint32', 'array'],
- object : [
- {int8: ['int8'], int16: ['int16'], string: ['string'], astring: ['astring']}
- ],
- aobject : [
- {int8: ['int8'], int16: ['int16'], string: ['string'], astring: ['astring']},
- 'array'
- ],
- astring: ['string', 'array']
- }
- var msg = {
- int8 : 12,
- int16 : 1234,
- int32 : 12345,
- uint8 : 130,// > 128
- uint16 : 32800, // >> 128 * 256
- uint32 : 3221245472, // >> 3 * (1<<30)
- string : 'hello world',
- aint8 : [-1, -2, -3, -5, -6],
- aint16 : [-11, -12, -13, -15, -17],
- aint32 : [-337, -338, -339, -3310, -3311],
- auint8 : [1, 2, 3, 4],
- auint16: [8, 9, 10, 11, 12],
- auint32: [12, 13, 15, 16],
- object : {int8: 12, int16: 1234, string: 'somebady', astring: ['save me', 'Dont stop me now']},
- 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']}],
- astring: ['melo', 'kaka', 'much', 'save']
- }
- var buf = Struct.pack(proto, msg);
- console.log(buf);
- var remsg = Struct.unpack(proto, buf);
- console.log(JSON.stringify(remsg));
【转】参照protobuf,将json数据转换成二进制在网络中传输。的更多相关文章
- 【转】C#中将JSon数据转换成实体类,将实体类转换成Json
http://wo13145219.iteye.com/blog/2022667 http://json2csharp.chahuo.com/ using System; using System.C ...
- 利用JAVA反射机制将JSON数据转换成JAVA对象
net.sf.json.JSONObject为我们提供了toBean方法用来转换为JAVA对象, 功能更为强大, 这里借鉴采用JDK的反射机制, 作为简单的辅助工具使用, 有些数据类型需要进行转 ...
- 将JSON数据转换成JAVA的实体类
思路:首先将JSON格式的数据转换成JSONObject,然后将JSONObject转换成Java的实体类(其中类属性包括List等类型) Java实体类: SearchFilter 类 1 publ ...
- 把HDFS里的json数据转换成csv格式
1. 全景图 2. 用ListHDFS获取所有文件名 如果想重新再取一次,右健view state: 点击 clear state, 再运行,即可再次采集数据了. 3. 用FetchH ...
- 把json数据转换成集合
Sting MessageList="";JSONArray json = JSONArray.fromObject(MessageList);JSONObject object ...
- 4.使用Jackson将Json数据转换成实体数据
Jar下载地址:http://jackson.codehaus.org/ 注意: 一.类中的属性名称一定要和Json数据的属性名称一致(大写和小写敏感),类之间的嵌套关系也应该和Json数据的嵌套关系 ...
- JSON数据转换成table表格
<%@ page contentType="text/html; charset=UTF-8" %> <%@taglib uri="/struts-ta ...
- json数据转换成结构体
package main import ( "encoding/json" "fmt" ) type IT1 struct { Company string ` ...
- Java中将JSON格式的数据转换成对应的Bean、Map、List数据
简单说明: 为了方便数据在客户端及服务器端的传输,有时候我们会用一些比较方便组织的数据类型,比如json.xml等传给客户端,客户端也可以重新组织数据传回服务器端.JSON和XML提供了一套比较方便的 ...
随机推荐
- BZOJ 4777: [Usaco2017 Open]Switch Grass
4777: [Usaco2017 Open]Switch Grass Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 46 Solved: 10[Su ...
- Android(java)学习笔记130:Android中操作XML数据(使用Pull解析器)
1. Pull解析器的运行方式与 SAX 解析器相似.它提供了类似的事件,如:开始元素和结束元素事件,使用parser.next()可以进入下一个元素并触发相应事件.跟SAX不同的是, Pull解析器 ...
- Android(java)学习笔记124:利用Service在后台播放背景音乐
1. 在android应用程序里,有一种没有UI的类(android.app.Service)——Service.简单来说,Service是一个 background process(背景程序),通过 ...
- PAT (Basic Level) Practise (中文)- 1008. 数组元素循环右移问题 (20)
一个数组A中存有N(N>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(M>=0)个位置,即将A中的数据由(A0A1……AN-1)变换为(AN-M …… AN-1 A0 ...
- 01_2_模拟spring装载bean
01_2_模拟spring装载bean 1. xml配置文件内容 beans.xml <beans> <bean id="u" class="com.w ...
- VueX源码分析(2)
VueX源码分析(2) 剩余内容 /module /plugins helpers.js store.js helpers要从底部开始分析比较好.也即先从辅助函数开始再分析那4个map函数mapSta ...
- JS数据结构及算法(一) 堆栈
最近在看<学习JavaScript数据结构与算法>这本书,感觉自己又涨知识了 哈哈... 现在将自己看的做个总结,也是巩固理解. 栈:先进后出,新添加和待删除的元素都保存在栈顶.可以用数组 ...
- php curl使用例子
PHP支持的由Daniel Stenberg创建的libcurl库允许你与各种的服务器使用各种类型的协议进行连接和通讯.libcurl目前支持http.https.ftp.gopher.telnet. ...
- thinkcmf5更新模板代码分析,解决模板配置json出错导致数据库保存的配置项内容丢失问题
private function updateThemeFiles($theme, $suffix = 'html') { $dir = 'themes/' . $theme; $themeDir = ...
- 【markdown】 markdown 语法
介绍几个 markdown 语法学习地址和相关工具 参考链接 coding gitlab markdown offical markdown editor markdown editor2