I'm currently experimenting with an idea for a project. For this, I had to write a script that recursively downloads a directory to my hard-drive using FTP.
I soon found out that when dealing with FTP and node.js, jsftp is the way to go as long as you don't need to support SFTP.
Here is the steps I had in mind when writing my script:
Points 1 and 2 worked intuitively by writing a recursive function that uses jsftp's ftp.ls
-function to walk the remote directory.
I thought I could now just iterate through the directory-listing that I had saved to an array and download each file. In code, this looked something like this:
remoteFiles.forEach(function(file) {ftp.get(file.path, targetPath, function(err) {if (err) return cb(err)console.log('downloaded ' + file.path)cb()})})
However, nothing really happened. All I got, was a big, confusing (to me at least) error called ECONNREFUSED
. I did a bit of Googling and read some stuff about firewalls but that wasn't the issue.
The issue was: I was creating too many connections to the ftp-server simultaneously.
jsftp
doesn't have a built-in functionality for limiting the number of concurrent connections, but it's still really easy by using the async-library.
There's a method called eachLimit that does just what we want. Everything works fine if we do something like this:
async.eachLimit(remoteFiles,1,function(file, cb) {ftp.get(file.path, targetPath, function(err) {if (err) return cb(err)console.log('downloaded ' + file.path)cb()})},function(err) {if (err) return console.log(err)console.log('all files were downloaded')})
Of course there's some more logic required for dealing with "downloading" directories but the eachLimit-approach should solve your problems when dealing with the ECONNREFUSED
-error in this case.
Hi, I’m Max! I'm a fullstack JavaScript developer living in Berlin.
When I’m not working on one of my personal projects, writing blog posts or making YouTube videos, I help my clients bring their ideas to life as a freelance web developer.
If you need help on a project, please reach out and let's work together.
To stay updated with new blog posts, follow me on Twitter or subscribe to my RSS feed.