当我通过流管道类似图像文件的东西时,有没有办法随之发送元对象?
我的服务器从用户发送图像。图像被推送通过一组执行各种操作的流。
最终流发出data
事件,它将生成的图像缓冲区传递给回调,但是我丢失了用户的所有上下文。我需要将结果图像与用户的id和其他一些元数据联系起来。
理想:
stream.on('data', function(img, meta){
...
})
感谢任何可能的解决方案!
答案 0 :(得分:4)
简而言之,不,Node.js中没有内置任何东西来支持包含流的元数据。不过,您确实有其他选择,包括:
您可以使用闭包来跟踪与流分开的元数据。例如:
function handleImage(imageStream) {
var meta = {...};
imageStream.pipe(otherStreams).on('data', function(image) {
// you now have `image` and `meta` variables at your disposal here.
}
}
这样做的缺点是您的otherStreams
无法使用元数据。
如果您的其他流是您无法控制的第三方代码,如果他们不需要了解元数据,那么这是一个很好的解决方案。
您可以执行类似于HTTP标头的操作,其中到某一点的所有数据都是元数据,其后的所有内容都是图像。 (在HTTP中,分隔符是\n\n
首先出现的地方。)链中的所有流都必须知道并处理它。
如果您知道您的元数据将始终位于一个块中,并且您的所有流都没有拆分或合并块,那么您可以稍微简化一下,然后说第一个(或最后一个)块始终是元数据。
切换到答案中提到的像Amoli这样的对象流。在这里你将通过{image: imgData, meta: {...}}
。然后,您必须更新其他流以期望此格式。
但是,这种方法的主要缺点是,您必须多次传递元数据,将其缓存到需要它的每个流的某个位置,或者将整个图像作为一个块传递(哪种方式会杀死整个点) “溪流”)。而且,据我所知,node.js可以比对象流更好地优化文本/二进制流。所以,这可能不适合你的情况。
https://github.com/dominictarr/mux-demux可能会对您有所帮助。它将多个流组合成一个,因此您可以拥有单独的图像和元流。我不确定它对你的情况有多好。您可能需要更新所有流以了解它。
我知道我说除了第一个选项之外的所有选项都需要修改其他流,但是有一种解决方法:你可以创建一个通用的“流包装器”来分割图像和元数据并仅传递图像数据通过主流,并让元数据绕过它并继续下一个链。虽然这很难看,所以可能不是最好的主意。
答案 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)。