【问题标题】:Javascript: Send Array of ints through node.js binary websocketsJavascript:通过 node.js 二进制 websockets 发送整数数组
【发布时间】:2013-09-18 05:22:09
【问题描述】:

我有以下情况。我通过带有context.getImageData().data 的画布捕获网络摄像头帧。当我 console.log() 他们时,这给了我一个很好的数组(或 UInt8ClampedArray 说 Bidelman)像 [r, g, b, a, r, g, b, a, r, g, b, a, etc.] 这样的整数。现在我想通过 binaryjs 将它发送到 node.js 服务器,当然数据会像地狱一样被打乱:https://gist.github.com/thgie/6550638

如何先将数组转换为二进制文件,或者如何将二进制文件恢复为可读数组?

代码示例

客户:

client.send(ctx.getImageData(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT).data, {'id': 'bin', 'frame': frame});

服务器:

client.on('stream', function(stream, meta){

  var bufs = [];

  stream.on('data', function(data){
    bufs.push(data);
  });

  stream.on('end', function(){

    var buf = Buffer.concat(bufs);

    fs.writeFile(__dirname + "/tmp/"+meta.frame+".dat", buf, "binary", function(err) {
      if(err) {
        console.log(err);
      } else {
        console.log("The file was saved!");
      }
    });
  });
}

看起来像这样:

H>DÿNDJÿL@FÿPCJÿR@KÿQ?IÿLDPÿKCOÿMCKÿLAIÿL@DÿL@DÿLBGÿKAFÿIAHÿLDLÿLAIÿLAIÿO@IÿO@IÿIAJÿJBKÿMCIÿNDJÿQEIÿQEIÿPGHÿOFGÿMIHÿMIHÿPDFÿNCEÿIBDÿLEHÿPDFÿPDFÿMHLÿLGKÿMHLÿNIMÿOGLÿNFKÿOEMÿPFNÿRFSÿPERÿPERÿPERÿRGOÿSHPÿSGMÿSGMÿRJRÿQIPÿQJNÿRKPÿRKPÿQJNÿSGMÿSGMÿOHJÿSLOÿQJLÿRKMÿSIJÿTKKÿQLPÿPJNÿSLQÿRKPÿSLQÿUMRÿSKSÿUMTÿVMWÿSKUÿUJUÿRGQÿUMTÿUMTÿSKUÿVMWÿSMTÿSMTÿQNVÿQNVÿSMVÿTNWÿZMVÿXKTÿUJUÿVKVÿTOSÿTOSÿWQUÿWQUÿYTVÿYTVÿXRVÿUPTÿYSZÿYSZÿXRVÿZUYÿWPRÿYRTÿWRQÿXSRÿVOOÿWPPÿXRVÿXRVÿZOYÿ[P[ÿZO[ÿ\Q^ÿZT_ÿZT_ÿZV`ÿZV`ÿ]T^ÿ]T^ÿ^TZÿ`V[ÿ[VXÿ[VXÿ]UZÿ^V[ÿZV`ÿ[Waÿ_Xdÿ_Xdÿ]X`ÿ]X`ÿaZ_ÿaZ_ÿ_Y]ÿ`[_ÿ`Y]

【问题讨论】:

  • 如果您使用的是 binaryjs,那么它会为您完成。确保您在服务器端和客户端使用 binaryjs 进行通信,它会为您处理压缩和解压缩。
  • 那我对缓冲区做错了。因为无论我如何转换它,我都会得到混乱的痕迹。
  • 您传递给fs.writeFilebuf 参数是一个实际的缓冲区,对吧?显然,有些东西正在对您的数据进行字符串化。
  • 我很确定这是一个缓冲区。来自 binaryjs 的文档:在 Node.js 上,二进制数据作为缓冲区接收。但我不发送二进制数据。我发送了一个数组,但我不相信 binaryjs 可以为我解决这个问题。也许如果我发送一个 ArrayBuffer。

标签: javascript node.js binary websocket


【解决方案1】:

就浏览器而言,您可以使用 chrome 的开发工具轻松验证。查看二进制流量,它会告诉您是否发送二进制文本帧。它们是 websocket 规范中不同类型的框架。

在节点方面,您可以使用Buffer.isBuffer() 验证您的缓冲区值是真正的节点缓冲区。我看到您正在使用“二进制”字符串编码编写缓冲区。这可能不是你想要的。在节点中,本机Buffer 实例的编码为null"binary""ascii""utf8""hex""base64" 编码都是字符串编码/解码。二进制编码的意思是每个字节都作为一个 8 位的 unicode 码点存储在字符串中。

// Convert a binary buffer into a "binary" encoded string.
function binaryEncode(buffer) {
  var string = "";
  for (var i = 0, l = buffer.length; i < l; i++) {
    string += String.fromCharCode(buffer[i]);
  }
  return string
}

// Convert a "binary" encoded string into a binary buffer.
function binaryDecode(string) {
  var length = string.length;
  var buffer = new Buffer(length);
  for (var i = 0; i < length; i++) {
    buffer[i] = string.charCodeAt(i);
  }
} 

因此可以在 JavaScript 字符串(定义为每个字符具有 16 位 unicode 代码点)中非常安全地存储二进制数据。这不是最有效的事情,因为您浪费了每个字符的高 8 位,这就是 node.js 更喜欢原生缓冲区的原因。但在浏览器加密库之类的东西中,这种“二进制”字符串编码很常见,因为它在所有 JS 平台上都受支持。

【讨论】:

    猜你喜欢
    • 2012-11-16
    • 2012-12-05
    • 2014-11-30
    • 2013-11-26
    • 1970-01-01
    • 2013-03-07
    • 2012-01-02
    • 1970-01-01
    相关资源
    最近更新 更多