Использование загрузки файла Sailsjs Skipper с помощью Flowjs
Я пытаюсь использовать skipper и flowjs с ng-flow для загрузки больших файлов.
На основе примера для Nodejs, расположенного в репозитории flowjs, я создал свой контроллер sails и сервис для обработки загрузки файлов. Когда я загружаю небольшой файл, он работает нормально, но если я пытаюсь загрузить больший файл (например, видео размером 200 Мб), я получаю ошибки (перечисленные ниже) и массив req.file('file')._files
пустой. Интересен тот факт, что это происходит только несколько раз при загрузке. Например, если flowjs разрезает файл на 150 фрагментов, в консоли sails эти ошибки будут появляться только 3-5 раз. Таким образом, почти все фрагменты будут загружены на сервер, но некоторые из них будут потеряны, а файл результатов будет поврежден.
verbose: Unable to expose body parameter `flowChunkNumber` in streaming upload! Client tried to send a text parameter (flowChunkNumber) after one or more files had already been sent. Make sure you always send text params first, then your files.
Эти ошибки появляются для всех параметров flowjs.
Я знаю о том, что параметры текста должны быть отправлены в первую очередь для корректной работы с шкипером. И в сетевой консоли Chrome я проверил, что flowjs отправляет эти данные в правильном порядке.
Какие-либо предложения?
Контроллер метод
upload: function (req, res) {
flow.post(req, function (status, filename, original_filename, identifier) {
sails.log.debug('Flow: POST', status, original_filename, identifier);
res.status(status).send();
});
}
Сервисный пост метод
$.post = function(req, callback) {
var fields = req.body;
var file = req.file($.fileParameterName);
if (!file || !file._files.length) {
console.log('no file', req);
file.upload(function() {});
}
var stream = file._files[0].stream;
var chunkNumber = fields.flowChunkNumber;
var chunkSize = fields.flowChunkSize;
var totalSize = fields.flowTotalSize;
var identifier = cleanIdentifier(fields.flowIdentifier);
var filename = fields.flowFilename;
if (file._files.length === 0 || !stream.byteCount)
{
callback('invalid_flow_request', null, null, null);
return;
}
var original_filename = stream.filename;
var validation = validateRequest(chunkNumber, chunkSize, totalSize, identifier, filename, stream.byteCount);
if (validation == 'valid')
{
var chunkFilename = getChunkFilename(chunkNumber, identifier);
// Save the chunk by skipper file upload api
file.upload({saveAs:chunkFilename},function(err, uploadedFiles){
// Do we have all the chunks?
var currentTestChunk = 1;
var numberOfChunks = Math.max(Math.floor(totalSize / (chunkSize * 1.0)), 1);
var testChunkExists = function()
{
fs.exists(getChunkFilename(currentTestChunk, identifier), function(exists)
{
if (exists)
{
currentTestChunk++;
if (currentTestChunk > numberOfChunks)
{
callback('done', filename, original_filename, identifier);
} else {
// Recursion
testChunkExists();
}
} else {
callback('partly_done', filename, original_filename, identifier);
}
});
};
testChunkExists();
});
} else {
callback(validation, filename, original_filename, identifier);
}};
редактировать
Найдено решение для установки свойства flowjs maxChunkRetries: 5
потому что по умолчанию это 0
, На стороне сервера, если req.file('file')._files
пусто я выкидываю не постоянную (в контексте flowjs) ошибку.
Итак, это решает мою проблему, но вопрос, почему он так себя ведет, все еще остается открытым. Пример кода для использования flowjs и Nodejs connect-multiparty
и не имеет никакого дополнительного кода обработки ошибок, так что, скорее всего, это ошибка bodypperparser.