尝试将文件从存储上传到通过云功能传递的FTP服务器时超时

时间:2018-05-29 09:19:12

标签: node.js firebase ftp google-cloud-functions firebase-storage

我正在尝试将文件从存储上传到FTP服务器时遇到问题,并通过触发节点js函数传递。

因此,每次将具有特定名称的文件上载到Firebase存储时,此文件都应自动上传到FTP服务器。 为此,我使用的是promise-ftp。 我能够连接到服务器,但是当涉及到上传文件时,我面临着连接超时。我尝试了另一个节点包。同样的问题。

但是,当我在本地执行js脚本而不通过触发器时,文件已成功上传。

我在本地尝试的promise-ftp脚本如下:

function test() {
  var ftp = new PromiseFtp();
  const tempFilePath = path.join(os.tmpdir(), '123.pdf');
  ftp.connect({host: 'ftp.aaa-bbbb.ccc', user: 'aaabbb', password: 'pswd123'})
  .then(function (serverMessage) {
    console.log(serverMessage);
    return ftp.put(tempFilePath, 'local.pdf');
  })
  .then(function () {
    return ftp.end();
  })
  .then(() => {
    console.log("Ready to delete");
     // Once the pdf has been uploaded delete the local file to free up disk space.
    fs.unlinkSync(tempFilePath);
  });
}

节点js可以使用相同的代码,但文件名和目的地名称不同。

有什么想法吗?

更新#1

exports.updateToFTP = functions.storage.object().onFinalize((object) => {
    // [START eventAttributes]
    const fileBucket = object.bucket; // The Storage bucket that contains the file.
    const filePath = object.name; // File path in the bucket.
    const contentType = object.contentType; // File content type.
    const resourceState = object.resourceState; // The resourceState is 'exists' or 'not_exists' (for file/folder deletions).
    const metageneration = object.metageneration; // Number of times metadata has been generated. New objects have a value of 1.
    // [END eventAttributes]

  // [START stopConditions]
  // Exit if this is triggered on a file that is not an image.
  if (resourceState === 'exists') {
    // ignore for deletions
    return
  }
  if (!contentType.startsWith('application/pdf')) {
    return null;
  }
  // [END stopConditions]
  // Get the file name.
  const fileName = path.basename(filePath);
  // get file from bucket.
  const bucket = gcs.bucket(fileBucket);
  const tempFilePath = path.join(os.tmpdir(), fileName);
  var ftp = new PromiseFtp();
  return bucket.file(filePath).download({
    destination: tempFilePath,
  }).then(() => {
    return ftp.connect({host: 'host', user: 'usr', password: 'pwd'})
  }).then(function (serverMessage) {
    console.log(serverMessage);
    return ftp.put(tempFilePath, fileName);
  }).then(function () {
    return ftp.end();
  })
  .then(() => {
    console.log("Ready to delete");
     // Once the pdf has been uploaded delete the local file to free up disk space.
    fs.unlinkSync(tempFilePath);
  }).catch((err) => {
      console.log("Catching error");
      console.log(err)
  });
})

错误:(仅限ftp包)

Timed out while making data connection
    at Timeout._onTimeout (/user_code/node_modules/ftp/lib/connection.js:901:12)
    at ontimeout (timers.js:386:11)
    at tryOnTimeout (timers.js:250:5)
    at Timer.listOnTimeout (timers.js:214:5)

承诺ftp的随机错误(无法在本地重现):

ReferenceError: reentry is not defined
    at /user_code/node_modules/promise-ftp/node_modules/@icetee/ftp/lib/connection.js:937:18
    at Timeout._onTimeout (/user_code/node_modules/promise-ftp/node_modules/@icetee/ftp/lib/connection.js:962:9)
    at ontimeout (timers.js:386:11)
    at tryOnTimeout (timers.js:250:5)
    at Timer.listOnTimeout (timers.js:214:5)

将文件从存储上传到FTP可能是一种不好的做法......

3 个答案:

答案 0 :(得分:1)

您可能已经对Flame计划的出站网络设置了限制(每月5 GB)。您可以升级到Blaze计划,以获得按使用付费的无限制网络。

答案 1 :(得分:1)

Firebase功能有时间限制,因此如果您的文件很大或者您的网络延迟会导致文件传输时间延长,则该功能会超时。

以下是firebase指定的限制的链接:https://cloud.google.com/functions/quotas#time_limits

如果文件大小非常大并且将文件拉到服务器,您可以使用触发器使用stoage文件可下载URL调用webhook。

答案 2 :(得分:0)

几个小时后,我看到了@icetee 上的提交,我发现了这个。所以你所要做的就是:

  1. 转到 node_modules\promise-ftp\node_modules@icetee\ftp\lib\connection.js
  2. 寻找this._send(pasvCmd, function(err, text) {
  3. 替换为 this._send(pasvCmd, function reentry(err, text) {

我不知道为什么这个错误一直出现在实际版本中