簡體   English   中英

Node.js [promise-ftp] - 從 FTP 下載多個文件時無法建立數據連接(錯誤:連接 ECONNREFUSED...)

[英]Node.js [promise-ftp] - Unable to make data connection (Error: connect ECONNREFUSED...) while downloading multiple files from FTP

嘗試使用promise-ftpftp下載多個圖像時出現此錯誤。 我可以看到在出現此錯誤之前正在下載一些圖像。

無法建立數據連接(錯誤:連接 ECONNREFUSED...)

在我的場景中,客戶端發送 ftp 的特定目錄路徑,所有圖像都應從中下載到服務器。

這是我的代碼:

最初uploadData包含來自客戶端的數據,從中獲取目錄路徑。

router.post("/addPhotos", async (req, res) => {
  try {
    let uploadData = req.body;

    if (!uploadData) {
      handleError("Error! Invalid data received.", res);
      return;
    }

    await getPhotosWithCaptionsAndPath(uploadData)
      .then(uDataWithCaptionsAndPath => {
        uploadData = uDataWithCaptionsAndPath;

        res.status(200).send({
          data: "Images Uploaded successfully!",
          success: true,
          error: null
        });
      })
      .catch(err => {
        handleError(err, res);
      });

    //insert uploadData to db . . .
  } catch (err) {
    handleError(err, res);
  }
});

getPhotosWithCaptionsAndPath = uploadData => {
  return new Promise(async (resolve, reject) => {
    try {
      let output = [];
      let fileCount = 0;

      //get total # of images in all directories
      await getfileCount(uploadData)
        .then(fc => (fileCount = fc))
        .catch(err => reject(err));

      //download images and generate output array for db rows
      const ftp = new PromiseFtp();
      await ftp
        .connect({
          host: env.ftp.host,
          user: env.ftp.user,
          password: env.ftp.password
        })
        .then(serverMessage => {
          //looping through each directory
          uploadData.forEach(async (v, i) => {
            // calc directory path
            /* prettier-ignore */
            let uri = `/${
              v.schoolName
            }/${
              v.studentClass.toString()
            }-${
              v.studentSection
            }/${
              v.studentName
            }`;

            await ftp
              .list(uri, false)
              .then(list => {
                //looping through each image file
                list.forEach((val, index) => {
                  uploadFtpFile(ftp, uri, val, output)
                    .then(outputFromUFF => {
                      output = outputFromUFF;
                      if (fileCount === output.length) {
                        ftp.end();
                        resolve(output);
                      }
                    })
                    .catch(err => reject(err));
                });
              })
              .catch(err => reject(err));
          });
        });
    } catch (err) {
      reject(err);
    }
  });
};

uploadFtpFile = (ftp, uri, val, output) => {
  return new Promise((resolve, reject) => {
    try {
      ftp.get(uri + "/" + val.name).then(stream => {
        let fileName = `ph${Date.now()}.png`;
        let file = fs.createWriteStream("./uploads/" + fileName);
        output.push({
          url: fileName,
          caption: val.name.replace(/\.[^/.]+$/, "")
        });

        stream.pipe(file);
        stream.once("close", () => {
          resolve(output);
        });
        stream.once("error", reject);
      });
    } catch (err) {
      reject(err);
    }
  });
};

getfileCount = uploadData => {
  return new Promise((resolve, reject) => {
    try {
      let fileCount = 0;
      const ftpC = new PromiseFtp();
      ftpC
        .connect({
          host: env.ftp.host,
          user: env.ftp.user,
          password: env.ftp.password
        })
        .then(serverMessage => {
          uploadData.forEach(async (v, i) => {
            /* prettier-ignore */
            let uri = `/${
            v.schoolName
          }/${
            v.studentClass.toString()
          }-${
            v.studentSection
          }/${
            v.studentName
          }`;
            await ftpC
              .list(uri, false)
              .then(async list => {
                fileCount += list.length;
                if (i === uploadData.length - 1) resolve(fileCount);
              })
              .catch(err => reject(err));
          });
        })
        .catch(err => reject(err));
    } catch (err) {
      reject(err);
    }
  });
};

FTP 有一個限制,因此從 FTP 批量上傳/下載內容不是一個好主意,您需要將foreach循環轉換為for循環,這將允許按順序處理每個文件,這可能會延遲您的過程,但將是故障安全的。

所以你可以改變這個片段

for (let  i = 0; i < list.length; i++) {
  let val = list[i]
  uploadFtpFile(ftp, uri, val, output)
  .then(outputFromUFF => {
     output = outputFromUFF;
     if (fileCount === output.length) {
        ftp.end();
        resolve(output);
     }
   })
   .catch(err => reject(err));
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM