node 第八章 二进制协议与json协议

二进制数据协议

1: 客户端与服务器约定一种方式来传送数据;

2: 发送端: 将要发送的数据对象根据商定的协议 打包成二进制数据;

3: 接收端 将收到的二进制数据根据商定的协议解码成数据对象;

4: 二进制的优点: 包的体积小 缺点: 可读性不强,每个命令有对应的编码和解码;

5: 大型的对数据包体积敏感的游戏一般采用二进制协议,每个命令对应的编码和解码。使用 工具根据协议的描述文件自动生成代码代表有 protobuf工具;

json数据协议

1:发送端直接把数据对象 转成json文本格式;

2: 接收端直接把json文本转回来数据对象;

3: 优点: 简单,直观 缺点: 体积比二进制要大;

4: 尽量用数字作为索引,而不用名字的key,减少体积

var bin_encode = {
   0: {
      // 账号登陆的二进制协议打包, stype = 0, cmd_type = 1,
      // data.uname 存放数据名字, data.upwd = 密码 {uname: "xxxx", upwd = "xxxx };
      // 制定了我们的登陆命令协议,前个字节存放服务号,后两个字节我们存放命令号,后面我们存放uname字符串的长度,占2个字节;
      // 紧接着uname字符串的内容,接着是upwd的长度信息,占两个字节,紧接着是upwd的内容;
      1: function (data) { // encode_login_cmd 
         // 前面2个字节来存放我们的服务号
         var cmd_len = 2 + 2 + 2 + data[0].length + 2 + data[1].length;
         var cmd_buf = Buffer.allocUnsafe(cmd_len);

         // 写入两个字节的服务号
         cmd_buf.writeUInt16LE(0, 0); // 写入了0号服务
         cmd_buf.writeUInt16LE(1, 2); // 紧跟两个字节,我们写这个命令的命令号
         // end 

         // 数据体
         // uname
         var len = data[0].length;
         cmd_buf.writeUInt16LE(len, 4); // 写入了0号服务
         cmd_buf.fill(data[0], 4 + 2);

         // upwd
         len = data[1].length;
         var offset = 6 + data[0].length;
         cmd_buf.writeUInt16LE(len, offset); // 写入了0号服务
         cmd_buf.fill(data[1], offset + 2);
         // end 

         return cmd_buf;
      },

   },

};

var bin_decode = {
   0: {
      // return 
      1: function(cmd_buf) {
         var cmd = {
            0: 0,
            1: 1,
            2: null,
         };

         var len = cmd_buf.readUInt16LE(4); // uname的长度
         var offset = 4 + 2;
         
         var data = {};

         data.uname = cmd_buf.toString("utf8", offset, len + offset);

         offset += len;
         len = cmd_buf.readUInt16LE(offset); // uname的长度
         offset += 2;
         data.upwd = cmd_buf.toString("utf8", offset, len + offset);       
         
         cmd[2] = data; 
         return cmd;
      },

   }
}

function bin_encode_cmd(stype, cmd_type, data) {
   if (bin_encode[stype] && bin_encode[stype][cmd_type]) {
      return bin_encode[stype][cmd_type](data);
   }

   return null;
}

function bin_decode_cmd(cmd_buf) {
   // 前面2个字节是服务号,接着两个字节是命令号
   var stype = cmd_buf.readUInt16LE(0);
   var cmd_type = cmd_buf.readUInt16LE(2);
   if (bin_decode[stype] && bin_decode[stype][cmd_type]) {
      return bin_decode[stype][cmd_type](cmd_buf);
   }

   return null;
   // end 
}

var bin_protocol = {
   encode: bin_encode_cmd,
   decode: bin_decode_cmd,
}


function json_encode(stype, cmd_type, data) {
   var data = {
      0: stype,
      1: cmd_type,
      2: data,
   };

   var cmd_buf = JSON.stringify(data);
   console.log(cmd_buf);

   return cmd_buf;
}

function json_decode(cmd_buf) {
   var cmd_data = JSON.parse(cmd_buf);
   console.log(cmd_data);
   return cmd_data;
}

var json_protocol = {
   encode: json_encode,
   decode: json_decode,
}
module.exports = bin_protocol;
// module.exports = json_protocol;

你可能感兴趣的:(nodejs)