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



当我尝试将文件从存储上传到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的不良做法...

Firebase 函数有时间限制,因此如果您的文件大小很大,或者您的网络延迟导致文件传输时间增加,则该函数将超时。

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

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

您可能遇到了 Flame 计划的出站网络限制(每月 5 GB(。 您可以升级到 Blaze 计划以实现按使用付费的无限网络。

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

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

我不知道为什么这个错误保持实际版本

最新更新