我目前有一个网关服务器,它接收多部分表单请求,其中每个请求包含一个文件和一些字段(用户 ID、文件名等)。在服务器进行一些验证和其他一些事情之后,我想将带有几个不同字段的原始文件发送到我的一个单独的文件存储服务器。换句话说,我更改了字段,保持文件不变,然后将其发送到第二台服务器。
我目前大约 80% 的时间都在工作,但其余时间我在存储服务器上收到错误消息,错误:由于多部分数据意外结束,部分提前终止。(发生在评论“此处打印错误”)。同样,此错误仅有时会发生。
网关服务器
const asyncBusboy = require( 'async-busboy' );
const request = reqwuire( 'request-promise' );
async function saveFile( context )
{
//parses the multipart form request. 'files' is an array of Readable Streams
const { files, fields } = await asyncBusboy( context.req ); //NEVER breaks here
if ( files.length == 0 )
return;
let form_data =
{
directory: 'my/files/directory',
filename: 'filename',
readstream: files[0]
//etc, etc, etc
};
let options =
{
method: 'POST',
uri: file_storage_server_url + '/song',
headers: { 'content-type': 'multipart/form-data' },
formData: form_data
};
await request( options ); //send to storage server
}
文件存储服务器
const asyncBusboy = require( 'async-busboy' );
async function saveFile( context )
{
const { files, fields } = await asyncBusboy( context.req ); //BREAKS HERE
//more stuff
}
AsyncBusboy
asyncBusboy 在内部做的是它在 /tmp 目录中创建一个临时文件,将传入文件的读取流通过管道传输到临时文件,创建一个到临时文件的读取流,并将其推送到上面的“文件”数组中。但是,我有时会收到我在管道过程中提到的错误。
function onFile(files, fieldname, file, filename, encoding, mimetype)
{
const tmpName = file.tmpName = new Date().getTime() + fieldname + filename;
const saveTo = path.join(os.tmpdir(), path.basename(tmpName));
file.on('end', () => {
const readStream = fs.createReadStream(saveTo);
readStream.fieldname = fieldname;
readStream.filename = filename;
readStream.transferEncoding = readStream.encoding = encoding;
readStream.mimeType = readStream.mime = mimetype;
files.push(readStream);
});
const writeStream = fs.createWriteStream(saveTo);
writeStream.on('open', () => {
console.log( "onFile onOpen" ); //Always prints
file.pipe( fs.createWriteStream(saveTo) );
});
//******* ERROR PRINTED HERE *********
file.on( 'error', (error) => { console.log( "Readstream error: " + error ); } );
}
我认为正在发生的事情
我认为存储服务器从 tmp 文件读取的速度比写入的速度快,导致它到达文件末尾并触发错误,由于多部分数据的意外结束,部分提前终止。
问题
我采取的总体方法是错误的吗?
async-busboy 在内部做事的方式根本上是错误的吗?
我该如何解决这个错误?