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
相关产品推荐
相关产品推荐

