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

xyhw6mcr  于 2023-03-06  发布在  Java
关注(0)|答案(3)|浏览(165)

我在节点服务器上使用Buffer,在Javascript客户机上使用Buffer
为了节省字节,我希望通过websockets以二进制而不是JSON的形式将数据发送到服务器。
因此,如果我有[ 5, false, 55, "asdf" ]的Javascript对象,我希望在发送之前将其转换为客户端上的缓冲区。

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

然后在服务器上读出来,就像这样:

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

我正在查看当前的解决方案,看起来我可能不得不做很多concat ing,指定字节偏移量/长度,从int转换为布尔值,等等。
有更好的办法吗?

    • 编辑:**以下是我认为您目前必须要做的事情。我想我的问题是它太冗长和容易出错,我正在寻找一种更简洁和优雅的方法来做它,因为这个操作将在我的代码中的许多不同位置执行。
// 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对象序列化到那个模式,并让它返回一个缓冲区,然后你可以在客户端/其他服务器上使用相同的模式反序列化缓冲区。我将进一步研究这个问题。
deikduxw

deikduxw1#

缓冲区的第一个参数必须是:字符串、缓冲区、ArrayBuffer、数组或类似数组的对象。

考虑到这些信息,我们可以通过从String创建一个缓冲区来实现您正在寻找的内容。

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' ]
kkbh8khc

kkbh8khc2#

当我们在NodeJS环境中时,我们有比Buffer.from(JSON.stringify(data))更好的选项。
性能方面,JSON.stringify + Buffer.from()是可以的,但是如果对象包含ArrayBuffer就不行了,如果这样做了,效率会很低。

纯NodeJS环境的最佳方式

使用“v8序列化API” NodeJS v8文档

它易于使用并内置于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。和C++,如果你想使用“V8”库(我个人不喜欢这样做)。

用于多平台支持

使用“bson”(蒙戈数据库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和计划很快推出这一网络JS。
tabular-json-node
由于它简单的表格结构,我们也可以支持其他平台。如果有人想在这方面合作,请随时联系。

nue99wik

nue99wik3#

我建议库@mrhiden/cstructhttps://www.npmjs.com/package/@mrhiden/cstruct
然后您可以交换二进制数据,如下所示:

import { CStructLE } from '@mrhiden/cstruct';
// Prepare exchange model and preset LE - Little Endian 
const cStruct = new CStructLE({ 
  first: 'int16', 
  second: 'bool8', 
  third: 'int16', 
  fourth: 'string4' 
});

// Make buffer with data
const { buffer } = cStruct.make({
  first: 5, 
  second: false, 
  third: 55, 
  fourth: "test" 
});

// Read bufer and extract data
const { struct } cStruct.read(buffer);
// struct: {
//  first: 5, 
//  second: false, 
//  third: 55, 
//  fourth: "test" 
//}

注:s4表示字符串最多允许4个字符。
或者:

const cStruct = new CStructLE({ 
  first: 'i16', 
  second: 'b8', 
  third: 'i16', 
  fourth: 's4' 
});

或者:

const cStruct = new CStructLE("{ 
  first: i16, 
  second: b8, 
  third: i16, 
  fourth: s4 
}");

相关问题