3

当我通过流传输图像文件之类的东西时,有什么方法可以发送元对象吗?

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

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

理想的:

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

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

4

3 回答 3

5

简而言之,不,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在这里可能会有所帮助。它将多个流合并为一个,因此您可以拥有单独的图像和元流。不过,我不确定它对您的情况有多好。您可能需要更新所有流以了解它。

我知道我说过除了第一个选项之外的所有选项都需要修改其他流,但是有一种解决方法:您可以创建一个通用的“流包装器”,它将图像和元数据拆分并仅将图像数据传递给主流,并让元数据绕过它并继续到链的下一个。不过,这很快就会变得丑陋,所以可能不是最好的主意。

于 2013-09-19T16:48:23.703 回答
1

基本上,每当您想读取或写入任何不是字符串或缓冲区的对象时,您都需要将您的流放入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);

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

了解更多信息:

于 2013-09-10T07:24:39.320 回答
0

metastream我为这种类型的东西创建了一个模块。(它在 npm 中)。

于 2015-02-07T02:00:37.443 回答