【问题标题】:node.js Socket hang up error while streaming an MP4 file from S3从 S3 流式传输 MP4 文件时 node.js 套接字挂起错误
【发布时间】:2014-09-12 20:33:40
【问题描述】:

我在 AWS S3 存储桶中有一个 MP4 文件。

视图代码是这样的:

<video width="300px" controls>
<source src="/getS3File/<full-s3-filename-here>" type="video/mp4">
</video>

而后端Node.JS代码是这样的:

exports.gets3file =  function(req, res, next) {
    var env = require("./env.js");
    var knox = require('knox');
    var s3filename = req.params.id;

    var submissionFileId = "https://TestS3File.amazonws.com/" + s3filename;  

    var s3Client = knox.createClient({
            key: aws.accessKey,
            secret: aws.secretKey,
            bucket: "testbucket"
    });

    s3Client.get(submissionFileId)
    .on('response', function(res) {    
        res.setHeader('Content-Length', res.headers['content-length']);
        res.setHeader('Content-Type', res.headers['content-type']);

        if (req.fresh) {
        res.statusCode = 304;
        res.end();
        return;
        }

        if (req.method === 'HEAD') {
        res.statusCode = 200;
        res.end();
        return;
        }

        res.pipe(req);
    });
    res.end();
    };

当我执行这段代码时,我在节点日志中看到了这个错误:

Error: socket hang up
at createHangUpError (http.js:1472:15)
at CleartextStream.socketOnEnd [as onend] (http.js:1568:23)
at CleartextStream.onCryptoStreamEnd (tls.js:322:24)
at CleartextStream.g (events.js:180:16)
at CleartextStream.emit (events.js:117:20)
at _stream_readable.js:943:16
at process._tickCallback (node.js:419:13)
at process._tickFromSpinner (node.js:394:15

关于:我可能做错了什么?

谢谢

【问题讨论】:

    标签: node.js amazon-web-services


    【解决方案1】:

    这里有一些问题:您正在传输到错误的流,您在文件开始流式传输之前立即结束您的响应,并且您正在使用 S3 中的 res 隐藏真实的 res要求。试试这样的:

    exports.gets3file =  function(req, res, next) {
      var env = require("./env.js");
      var knox = require('knox');
      var s3filename = req.params.id;
    
      var submissionFileId = "https://TestS3File.amazonws.com/" + s3filename;  
    
      var s3Client = knox.createClient({
        key: aws.accessKey,
        secret: aws.secretKey,
        bucket: "testbucket"
      });
    
      s3Client.get(submissionFileId)
      .on('response', function(s3res) {
        res.setHeader('Content-Length', s3res.headers['content-length']);
        res.setHeader('Content-Type', s3res.headers['content-type']);
    
        if (req.fresh) {
          res.statusCode = 304;
          res.end();
          return;
        }
    
        if (req.method === 'HEAD') {
          res.statusCode = 200;
          res.end();
          return;
        }
    
        s3res.pipe(res);
      }).end();
    };
    

    您可能还需要检查s3res.statusCode,以防文件不存在 (404),以便您可以将适当的状态代码发送回原始客户端。

    【讨论】:

    • 优点。我修复了您指出的所有问题,但仍然无法正常工作。我在 ".on('response'" 回调中放入了一个调试 stmt,看起来代码执行甚至没有进入该函数。
    • 我已经更新了代码。根据 knox 文档,即使是 GET,您仍然需要 end() S3 请求?
    • 我在我的代码中发现了另外 2 个错误(感谢您最初的评论)。我将这两行从:res.setHeader('Content-Length', res.headers['content-length']);res.setHeader('Content-Type', res.headers['content-type']); 更改为:res.setHeader('Content-Length', s3Res.headers['content-length']);res.setHeader('Content-Type', s3Res.headers['content-type']); 现在剩下的问题是运行时故障,上面写着:TypeError: Object #&lt;IncomingMessage&gt; has no method 'write'
    • 我应该补充一点,我还包括了您建议的 .end() 方法。与我在上一条评论中列出的错误相同
    • 您的response 回调末尾是否还有res.pipe(req);?它必须是s3res.pipe(res);
    猜你喜欢
    • 1970-01-01
    • 2014-12-06
    • 2011-08-01
    • 2014-10-29
    • 1970-01-01
    • 2018-05-07
    • 1970-01-01
    • 2018-04-29
    • 1970-01-01
    相关资源
    最近更新 更多