如何将Javascript对象转换为节点缓冲区?

时间:2016-07-08 20:01:17

标签: javascript node.js websocket buffer

我在我的节点服务器上使用Buffer,在我的Javacript客户端上使用Buffer

为了节省字节,我希望通过websockets作为二进制文件而不是JSON将数据发送到服务器。

因此,如果我有[ 5, false, 55, "asdf" ]的Javascript对象,我希望在发送之前将其转换为客户端上的缓冲区。也许是这样的:

object.toBuffer('int16', 'bool', 'int16', 'utf8');

并在服务器上阅读如下:

var obj = buffer.read('int16', 'bool', 'int16', 'utf8');

我正在查看当前的解决方案,看起来我可能只需要执行大量concat,指定字节偏移/长度,从整数转换为布尔值等。

有更好的方法吗?

编辑:以下是我认为您目前必须这样做的方式。我想我的问题只是它过于冗长且容易出错,而且我正在寻找一种更简洁,更优雅的方法,因为这个操作将在我的代码中的许多不同的地方执行。

// On client for [ 5, false, 55, "test" ]

const writeFirst = Buffer.allocUnsafe(2);
writeFirst.writeInt16LE(5, 0);
const writeSecond = Buffer.allocUnsafe(1);
writeSecond.writeUInt8(0);
const writeThird = Buffer.allocUnsafe(2);
writeThird.writeInt16LE(55, 0);
const writeFourth = Buffer.from('test');

const result = Buffer.concat([writeFirst, writeSecond, writeThird, writeFourth]);

// On server for reading buffer of [ 5, false, 55, "test" ]

const readFirst = result.readInt16LE(0);
const readSecond = Boolean(result.readUInt8(2));
const readThird = result.readInt16LE(3);
const readFourth = result.toString('utf8', 5);

编辑#2:谷歌搜索,我想我可能想要协议缓冲区之类的东西。我不确定它们是什么或者它们是否适用但看起来您可以在文件中为所有消息指定一个模式,然后将JSON对象序列化到该模式并让它返回一个缓冲区,然后可以在客户端/其他服务器上使用相同的模式进行反序列化。我还要再看一下这个。

2 个答案:

答案 0 :(得分:9)

缓冲区第一个参数必须是:String,Buffer,ArrayBuffer,Array或类似数组的对象。

考虑到这些信息,我们可以通过从字符串创建缓冲区来实现您要查找的内容。它看起来像下面这样:

let json = [ 5, false, 55, 'asdf' ];

let buffer = Buffer.from(JSON.stringify(json));
console.log('Buffer: ', buffer); // Buffer: <Buffer 5b 20 35 2c 20 66 61 6c 73 65 2c 20 35 35 2c 20 22 61 73 64 66 22 20 5d>

然后你可以像这样把你的JSON带回来:

let converted = JSON.parse(buffer);
console.log('Parsed to json', converted); // Parsed to json [ 5, false, 55, 'asdf' ]

答案 1 :(得分:2)

当我们在 NodeJS 环境中时,我们有比 Buffer.from(JSON.stringify(data)) 更好的选择。

性能明智的 JSON.stringify + Buffer.from() 没问题,但如果对象包含 ArrayBuffer 则无法解决,如果完成,则效率非常低。

纯基于 NodeJS 的环境的最佳方式

使用“v8 序列化 API”Node JS v8 docs

它易于使用并内置于 Node.js 二进制文件中。

在同类序列化器中速度最快、空间效率最高。

const { serialize, deserialize } = require("v8")

const photo = {
   name: "rabbit",
   height: 1220,
   width: 1440,
   tinyThumbnail: jpegFileAsBuffer,
   mediumThumbnail: anotherJpegFileAsBuffer,
   description: "some string data",
   metaData: {
     tags: ["rabbit", "animal", "runner"],
     type: "image/jpeg"
   }
}

const photoSerializedAsBuffer = serialize(photo)

const deserialisedBack = deserialize(photo)

但唯一的问题是,这只适用于 NodeJS。如果你想使用“v8”库,还有 C++(我个人不喜欢这样做)。

多平台支持

使用“bson”(MongoDB BSON)

在性能方面它接近 v8 解析器,但它可以适应所有支持 MongoDB 的平台、NodeJS、Web 中的 JS、Java、C++、rust、ruby、python....

用法和v8序列化API完全一样

const { serialize, deserialize } = require("bson")

const photo = {
   name: "rabbit",
   height: 1220,
   width: 1440,
   tinyThumbnail: jpegFileAsBuffer,
   mediumThumbnail: anotherJpegFileAsBuffer,
   description: "some string data",
   metaData: {
     tags: ["rabbit", "animal", "runner"],
     type: "image/jpeg"
   }
}

const photoSerializedAsBuffer = serialize(photo)

const deserialisedBack = deserialize(photo)

但是当 BSON 类型开始时会变得很困难。但是如果知道对象结构,这应该不是问题,并且在处理跨平台内容时不太可能不知道对象结构。

然而,NodeJS 中的一个快速解决方案是使用 bson-buffer

终于

这不是一个完整的证明解决方案,但非常适合 NodeJS,并计划很快为 Web JS 推出这个。

tabular-json-node

由于其简单的表格结构,我们也可以支持其他平台。如果有人想就此进行协作,请随时联系。