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

Guacamole SFTP大文件上传失败求助(超81字节即失效)

问题分析

你的SFTP上传功能仅支持81字节以内文件,大文件上传无回调且生成0字节空文件,核心问题有两个:

1. 未定义变量导致循环逻辑失效

代码中sent += tosend;的tosend变量未定义,小文件因单次循环就能完成上传(81字节小于分片大小1024),问题未暴露;大文件上传时sent无法正确累加,导致循环异常阻塞后续异步回调。

2. 同步循环发送异步数据触发流阻塞

Guacamole的BlobWriter.sendBlob()是异步操作,依赖guacd的ACK确认后才能继续发送下一块数据。直接用while循环同步发送所有分片,会导致大量未确认的消息积压,触发Guacamole内部流限制,最终导致上传中断,无任何回调返回。


修复后的代码

function UploadFileSFTP(path, filesystem, file, onprogress) {
  console.log('Uploading file ' + file.name + ' to ' + path);
  console.log('file type: ' + file.type);

  let stream = filesystem.createOutputStream(file.type, path);

  stream.onack = function beginUpload(status) {
    if (status.isError()) {
      console.log('Guacamole error on stream');
      console.log(status);
      return;
    }

    var blob_writer = new Guacamole.BlobWriter(stream, file.type);
    var slice_size = 1024;
    var sent = 0;

    blob_writer.onack = function packagereceived(status) {
      console.log('ack status: ');
      console.log(status);
      // 收到ACK后继续发送下一块数据
      sendNextChunk();
    };

    blob_writer.onerror = function uploadError() {
      console.log('upload error');
    };

    blob_writer.oncomplete = function uploadComplete() {
      console.log('upload complete');
    };

    function sendNextChunk() {
      if (sent >= file.size) {
        // 所有分片发送完毕,标记流结束
        blob_writer.sendEnd();
        return;
      }

      // 计算当前分片的实际大小(避免最后一块超出文件长度)
      var end = Math.min(sent + slice_size, file.size);
      var data = file.slice(sent, end);
      var chunkSize = end - sent;

      blob_writer.sendBlob(data);
      sent += chunkSize;

      console.log('Sent ' + sent + ' of ' + file.size + ' bytes');
      if (onprogress) {
        onprogress(sent / file.size);
      }
    }

    // 启动第一块数据发送
    if (file.size > 0) {
      console.log('uploading file of size: ' + file.size);
      sendNextChunk();
    } else {
      console.log('empty file, sending end');
      blob_writer.sendEnd();
    }
  };
}

关键修复点

  • 移除未定义的tosend变量,改用end - sent计算实际发送的分片大小,确保sent正确累加。
  • 将同步循环改为异步递推:每次收到guacd的ACK后再发送下一块数据,避免消息积压触发流限制。
  • 调整sendEnd()调用时机:仅在所有分片发送完毕后调用,而非oncomplete回调中(oncomplete是流结束后的通知,无需重复标记)。
  • 补充空文件处理逻辑,直接发送流结束标记。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 01:04:55