Express应用程序的app.post被多次调用

4
我一直在构建一款使用youtube-dl流式传输YouTube视频并保存的应用程序,一切都很正常,直到我尝试流式传输超过一个小时长的视频。当任务完成50%至100%,或者40至80秒时,整个代码块就会重新运行,导致多个同时流式传输发生。由于响应等待管道结束,因此无法发送响应。在流函数之外添加next()允许转换完成,而无需中断或重新运行代码块,但是在尝试发送响应时会导致以下错误:
Node.js代码块如下:
app.post('/convert/', function (req, res, next){
  var url = 'http://www.youtube.com/'+req.body.url;
  var quality = req.body.quality;
  var socketId = req.body.socketId;


stream = youtubedl(url, 
  ['-f ' + quality],

  // // Additional options can be given for calling `child_process.execFile()`. 
  { cwd: __dirname });

stream.on('info', function(info) {

  console.log('Download started');
  console.log('filename: ' + info._filename);
  console.log('size: ' + info.size);
  console.log('format: ' + info.format);

  var fileName = info._filename;
  var videoId = info.id;
  var videoTitle = info.title;
  videoTitle = videoTitle.replace(/[^a-zA-Z0-9\s]/g, '');
  console.log(videoTitle);

  var mp4 = 'downloads/'+videoTitle+'-'+info.format_id+'.mp4';
  fs.writeFile(mp4, "file", function(err) {
      if(err) {
          return console.log(err);
      }

    console.log("The file was saved!");
    var stat = fs.statSync(mp4);
    var str = progress({
      length: info.size,
      time: 100
    });

    str.on('progress', function(progress) {
      io.to(global.socketid).emit('progressVideo',{progress: progress.percentage});
      console.log(info.size);
      console.log(progress.transferred);
      console.log(progress.percentage);
      console.log(progress.remaining);
    });

    var pipe = stream.pipe(str).pipe(fs.createWriteStream(mp4));

    pipe.on('finish', function () {
      console.log("stream finished.");
      res.json(videoTitle+'-'+info.format_id+'.mp4');
    });
  });
 });
 // next();
});

被某些Angular代码调用。

// Sends youtube link to backend
$scope.getVideo = function(youtubeLink, resolution){
    var cleanedLink = youtubeLink.substring(24);
    var url = {url: cleanedLink, quality: resolution};
    $http.post('/convert/', url).success(function (response){
      // Do some stuff
    });
}

我很困惑为什么它会运行多次,因此我逐渐删除了更多的代码,直到只剩下这个简单的测试。

app.post('/convert/', function (req, res, next){
  console.log('hello!');
});

这段代码被一个ng-click事件调用,等待一分钟左右后,控制台还会打印出两个然后三个“hello!”语句。我完全不知道为什么会发生这种情况。如果有人能为我解释一下,那将不胜感激。

1个回答

5

在只使用基本的post路由并记录一些文本但未返回响应时,我得出结论问题出在node上。我决定记录每个console.log语句之间的时间长度,结果发现是每2分钟一次。通过这个,我能够找到如果没有发送回客户端响应,node会默认超时2分钟。

使用以下代码,我可以将响应设置为永不超时:

res.connection.setTimeout(0);

我希望这能帮助任何需要长时间保持连接以进行文件转换/传输等的人...


这个解决方案在本地可以工作,但在AWS服务器上无法工作。我已经增加了nginx的时间,但仍然会抛出错误。 - Lalitesh Upadhyaya

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接