你可以传递元数据与stream?

当我通过streampipe道像图像文件的东西有什么办法发送一个元对象一起吗?

我的服务器获取来自用户的图像。 图像通过执行各种操作的一组stream执行。

最后一个stream发出一个data事件,它将结果图像缓冲区传递给一个callback函数,但是我失去了用户的所有上下文。 我需要保持生成的图像绑定到用户的id和一些其他元数据。

理想:

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

感谢任何可能的解决scheme!

简而言之,不,Node.js中没有任何内容支持在stream中包含元数据。 不过,您还有其他select,其中包括:

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

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

    这个缺点是元数据不可用于其他otherStreams

    如果您的其他stream是不受您控制的第三方代码,或者不需要了解元数据,那么这是一个很好的解决scheme。

  2. 你可以做一些类似于HTTP标头的东西,在这里所有的数据都是元数据,后面的所有东西都是图片。 (在HTTP中,分隔符就是\n\n首先出现的任何地方。)链中的所有stream必须知道这个,然后处理它。

    如果你知道你的元数据将总是在一个块中,而你的stream中没有任何stream将它分割或合并,那么你可以简化一下,只是说第一个(或最后一个)块总是元数据。

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

    然而,这种方法的主要缺点在于,您必须多次传递元数据,将其caching到需要它的每个stream的某个位置,或将整个图像作为一个块传输(这种types会杀死整个“stream”点“)。 而且,从我所知道的情况来看,node.js可以比对象stream更好地优化文本/二进制stream。 所以,这可能不适合你的情况。

  4. https://github.com/dominictarr/mux-demux在这里可能会有所帮助。 它将多个stream合并成一个,所以你可以有独立的图像和元stream。 我不确定它将如何为你的情况工作。 您可能需要更新所有的stream以了解它。

我知道我说除了第一个选项外,其他的都需要修改其他的stream,但是有一个办法:你可以创build一个通用的“stream包装器”来分割图像和元数据,只传递图像数据通过mainstream,并有元数据绕过它,并继续下一个链。 这个变得很难看,所以可能不是最好的主意。

基本上,每当你想读或写任何不是string或缓冲区的对象,你需要把你的stream到objectMode

示例( 来源 ):

 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); 

我们将stream设置为使用objectMode,因为我们想要返回的不仅仅是数据,还有一些元数据。

了解更多信息:

  • Node.js文档stream对象模式
  • 节点stream的介绍

我为这种types创build了一个名为metastream的模块。 (这是npm)。