You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Node.js ssh2-sftp-client批量传多文件遇限问题求助

问题分析与解决方案

这个问题我太熟悉了——你现在的代码犯了一个常见的错误:重复对同一个SFTP客户端实例调用connect方法,这直接导致了监听器泄漏和上传失败。

为什么会出现警告和上传失败?

Node.js的EventEmitter默认最多允许10个同类型监听器,你循环12次调用sendFile,而每次sendFile里都会执行sftp.connect(config)。每次调用connect,都会给这个唯一的sftp实例添加新的ready、error、close监听器,当监听器数量超过10个时,Node就会抛出MaxListenersExceededWarning。

更关键的是,重复连接同一个客户端实例会导致连接状态混乱,后面的上传请求根本无法正常执行,所以超出10个的文件传不上去。

修复方案:一次连接,批量上传

正确的做法应该是先建立一次SFTP连接,再用这个已连接的实例执行所有上传操作,而不是每次上传都重新连接。下面是修改后的代码:

const Client = require('ssh2-sftp-client');

// 重构sendFile:不再处理连接逻辑,只负责单个文件的上传
const sendFile = (sftp, filename) => {
  console.log(filename);
  // 生成远程文件路径
  const remoteFilename = filename.substr(filename.lastIndexOf('/') + 1);
  const remotePath = `/home/pi/RetroPie/roms/atari2600/${remoteFilename}`;
  return sftp.put(filename, remotePath);
};

// 主上传流程:使用async/await让逻辑更清晰
const batchUpload = async (req, results) => {
  const sftp = new Client();
  try {
    // 只建立一次连接
    await sftp.connect(req.body);
    
    // 生成所有上传任务的Promise数组
    const uploadPromises = results.romlist.slice(0, 12).map(item => 
      sendFile(sftp, item.filename)
    );
    
    // 等待所有文件上传完成
    await Promise.all(uploadPromises);
    
    // 上传成功返回响应
    res.send('{"message":"OK"}');
  } catch (err) {
    console.log(err, '上传出错');
    // 出错时返回错误状态码
    res.status(500).send('{"message":"上传失败"}');
  } finally {
    // 无论成功或失败,确保关闭SFTP连接
    await sftp.end();
  }
};

// 触发批量上传(根据你的实际业务场景调整调用时机)
batchUpload(req, results);

关键改动说明

  1. 单次连接:把sftp.connect()移到主流程中,只执行一次,避免重复添加监听器
  2. 职责拆分:sendFile只专注于上传逻辑,依赖已连接的客户端实例
  3. 错误处理:使用try/catch/finally确保无论上传成功或失败,连接都会被关闭,避免资源泄漏
  4. 代码可读性:用async/await替代链式then,逻辑更直观

额外提示

如果你的业务场景需要同时处理超大量文件(比如几百个),可以考虑:

  • 限制并发上传数量(比如一次同时传5个),避免服务器压力过大
  • 若确实需要多个连接,可以创建多个Client实例,而不是修改监听器上限(虽然可以用sftp.setMaxListeners(0)取消限制,但不推荐,因为会隐藏潜在的内存泄漏问题)

内容的提问来源于stack exchange,提问作者user1864255

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:38:38