node.js - 从 node.js 报告上传进度

标签 node.js amazon-s3 formidable knox-amazon-s3-client

我正在编写一个小型 node.js 应用程序,它从 HTML 表单接收多部分 POST 并将传入数据通过管道传输到 Amazon S3。 formidable模块提供multipart parsing ,将每个部分公开为一个 Node Stream . knox模块处理 PUT 到 s3。

var form = new formidable.IncomingForm()
 ,  s3   = knox.createClient(conf);

form.onPart = function(part) {
    var put = s3.putStream(part, filename, headers, handleResponse);
    put.on('progress', handleProgress);
};

form.parse(req);

我正在通过 socket.io 向浏览器客户端报告上传进度,但很难让这些数字反射(reflect) Node 到 s3 上传的真实进度。

当浏览器到 Node 的上传几乎是瞬间发生时,就像 Node 进程在本地网络上运行时一样,进度指示器立即达到 100%。如果文件很大,即 300MB,进度指示器会缓慢上升,但仍比我们的上行带宽允许的速度快。在达到 100% 进度后,客户端会挂起,大概是在等待 s3 上传完成。

我知道 putStream 使用 Node 的 stream.pipe内部方法,但我不明白它是如何工作的细节。我的假设是 Node 尽可能快地吞噬传入的数据,并将其放入内存中。如果写入流可以足够快地获取数据,则很少有数据一次保留在内存中,因为它可以被写入和丢弃。但是,如果写入流很慢,就像这里一样,我们可能必须将所有传入的数据保留在内存中,直到可以写入为止。由于我们正在监听读取流上的 data 事件以发出进度,因此我们最终报告上传速度比实际速度快。

我对这个问题的理解是否接近标记?我该如何修复它?我需要用 writedrainpause 搞砸吗?

最佳答案

你的问题是 stream.pause isn't implemented on the part ,这是一个非常简单的多部分表单解析器输出的读取流。

Knox instructs the s3 request to emit "progress" events whenever the part emits "data" .但是,由于 part 流忽略了暂停,因此进度事件的发出速度与表单数据上传和解析的速度一样快。

然而,强大的 form 确实知道如何同时 pauseresume (它代理对它正在解析的请求的调用)。

这样的事情应该可以解决你的问题:

form.onPart = function(part) {

    // once pause is implemented, the part will be able to throttle the speed
    // of the incoming request
    part.pause = function() {
      form.pause();
    };

    // resume is the counterpart to pause, and will fire after the `put` emits
    // "drain", letting us know that it's ok to start emitting "data" again
    part.resume = function() {
      form.resume();
    };

    var put = s3.putStream(part, filename, headers, handleResponse);
    put.on('progress', handleProgress);
};

关于node.js - 从 node.js 报告上传进度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13311233/

相关文章:

node.js - 在 Windows 8 上安装 phonegap 时出现问题 - 未满足的依赖性

javascript - 使用 Handlebars 在 Ember Octane 中切换类的正确方法?

amazon-web-services - 使用 CloudFront 时,S3 上的自定义重定向规则返回 403

node.js - "Could not find a required file. Name: index.html"在Heroku上部署React应用程序时出错

node.js - 树莓派 mdns getaddrinfo 3008 错误

ios - AWS S3 HeadObject 无法解析 Dispatch_Once

amazon-web-services - S3 警告 : "No content length specified for stream data"

node.js - 如何使用formidable和express在node.js中上传多个图像

node.js flatiron - 通过 multipart/form-data 上传文件

javascript - formidable.parse 方法未执行,nodejs 和 formidable 包