你可以传递元数据和流吗?

时间:2013-09-10 06:30:52

标签: node.js stream

当我通过流管道类似图像文件的东西时,有没有办法随之发送元对象?

我的服务器从用户发送图像。图像被推送通过一组执行各种操作的流。

最终流发出data事件,它将生成的图像缓冲区传递给回调,但是我丢失了用户的所有上下文。我需要将结果图像与用户的id和其他一些元数据联系起来。

理想:

stream.on('data', function(img, meta){
   ...
})

感谢任何可能的解决方案!

3 个答案:

答案 0 :(得分:4)

简而言之,不,Node.js中没有内置任何东西来支持包含流的元数据。不过,您确实有其他选择,包括:

  1. 您可以使用闭包来跟踪与流分开的元数据。例如:

    function handleImage(imageStream) {
      var meta = {...};
      imageStream.pipe(otherStreams).on('data', function(image) {
         // you now have `image` and `meta` variables at your disposal here.
      }
    }
    

    这样做的缺点是您的otherStreams无法使用元数据。

    如果您的其他流是您无法控制的第三方代码,如果他们不需要了解元数据,那么这是一个很好的解决方案。

  2. 您可以执行类似于HTTP标头的操作,其中到某一点的所有数据都是元数据,其后的所有内容都是图像。 (在HTTP中,分隔符是\n\n首先出现的地方。)链中的所有流都必须知道并处理它。

    如果您知道您的元数据将始终位于一个块中,并且您的所有流都没有拆分或合并块,那么您可以稍微简化一下,然后说第一个(或最后一个)块始终是元数据。

  3. 切换到答案中提到的像Amoli这样的对象流。在这里你将通过{image: imgData, meta: {...}}。然后,您必须更新其他流以期望此格式。

    但是,这种方法的主要缺点是,您必须多次传递元数据,将其缓存到需要它的每个流的某个位置,或者将整个图像作为一个块传递(哪种方式会杀死整个点) “溪流”)。而且,据我所知,node.js可以比对象流更好地优化文本/二进制流。所以,这可能不适合你的情况。

  4. https://github.com/dominictarr/mux-demux可能会对您有所帮助。它将多个流组合成一个,因此您可以拥有单独的图像和元流。我不确定它对你的情况有多好。您可能需要更新所有流以了解它。

  5. 我知道我说除了第一个选项之外的所有选项都需要修改其他流,但是有一种解决方法:你可以创建一个通用的“流包装器”来分割图像和元数据并仅传递图像数据通过主流,并让元数据绕过它并继续下一个链。虽然这很难看,所以可能不是最好的主意。

答案 1 :(得分:1)

基本上,每当您想要读取或写入任何非字符串或缓冲区的对象时,您都需要将您的信息流放入objectMode

示例(source):

function S3Lister (s3, options) {
  options || (options = {});
  stream.Readable.call(this, { objectMode : true });

  this.s3 = s3; // a knox-like client.
  this.marker = options.start;
  this.connecting = false;
  this.ended  = false;
}

util.inherits(S3Lister, stream.Readable);

我们将流设置为使用objectMode,因为我们不仅要返回数据,还要返回一些元数据。

了解更多信息:

答案 2 :(得分:0)

我为这类事物创建了一个名为metastream的模块。 (现在是npm)。