【问题标题】:Downloading from MongDB GridFS stops working properly after a certain number of attempts to download在尝试下载一定次数后,从 MongoDB GridFS 下载停止正常工作
【发布时间】:2019-10-30 21:06:34
【问题描述】:

我想从我的 MongoDB 数据库下载一个文件。我发现使用 GridFS 存储桶的 openDownloadStream 可以在您将其通过管道传输到 Node 的 fs createWriteStream 时工作,然后在“完成”时将该数据发送到客户端以使用 res 下载进行下载。我的问题是,在几次尝试下载文件后,我的超时安全缓冲失败,客户端无法及时找到文件,然后浏览器给出空响应错误。但是,几秒钟后,文件最终会下载。

我正在将 mongoDB 集成到已经具有下载功能的现有服务器中。以前,文件存储在项目的文件系统中,现在它们在 MongoDB 中。我试过管道到不同的地方,但没有运气。

// Router's Download Logic
router.get("/download", function(req, res) {
  setTimeout(download, 2000);
  function download() {
      var bucket = new mongodb.GridFSBucket(localDatabase())
      bucket.openDownloadStreamByName(file)
        .pipe(fs.createWriteStream(file))
          .on('error', function(error) {
            assert.ifError(error)
          })
          .on('finish', function() {
            console.log(`Downloaded ${file}`)
            res.download(file)
            fs.access(file, function(err) {
              if (err) {
                console.log(err)
              }
              else {
                fs.unlinkSync(file)
              }
            })
          })
  }
});

我希望在 2 秒窗口后下载文件,让函数有足够的时间运行。在大约 3 次尝试下载后,我得到的是一个空响应错误。我最终得到了该文件,但似乎我在一个服务器实例中下载的越多,下载所需的时间就越长 -> 管道 -> createWriteStream。

编辑:问题来自取消链接。我更改了路径以转到 TEMP 文件夹,但我不想永远将这些文件存储在那里。我也不想在与下载它们相同的算法中取消它们的链接,因为这就是导致问题的原因。对此的任何建议都会有所帮助。

【问题讨论】:

    标签: node.js mongodb download gridfs


    【解决方案1】:

    正如编辑中所述,问题是与 res.download 几乎同时调用取消链接,这导致了挂断。为了避免那个小窗口,我在删除文件函数中添加了一个 setTimeout。一个可能的错误是当您下载两个文件的速度过快时,为了避免这种情况,我会提醒用户等待下载完成,然后再尝试再次下载。

    router.get("/download", function(req, res) {
      setTimeout(download, 1000);
      function download(callback) {
          var bucket = new mongodb.GridFSBucket(localDatabase())
          bucket.openDownloadStreamByName(file)
            .pipe(fs.createWriteStream('private/TEMP/' + file))
              .on('error', function(error) {
                assert.ifError(err)
              })
              .on('finish', function() {
                res.download('private/TEMP/' + file)
                console.log(`Downloaded ${file}`)
                setTimeout(removeFile, 1200)
              })
    
      }
      function removeFile() {
        fs.access('private/TEMP/' + file, function(err) {
          if (err) {
            console.log(err)
          }
          else {
            fs.unlinkSync('private/TEMP/' + file)
          }
        })
      }
    });
    

    【讨论】:

      猜你喜欢
      • 2020-11-29
      • 1970-01-01
      • 2017-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-08
      • 2020-05-03
      相关资源
      最近更新 更多