3

Я пытаюсь передать файл через WebRTC, и я изо всех сил пытаюсь найти хороший образец для записи данных по мере его поступления. Поскольку фрагменты файлов будут поступать по неизвестной ставке, мне нужно иметь возможность писать каждый кусок, когда он становится доступным; это означает две вещи:шаблон, управляемый событиями для записи фрагментов файла - JS

  1. если данные поступают слишком быстро, то мы должны стоять в очереди каждый кусок должен быть записан позже после того, как текущая задача записи закончена
  2. если данные поступают слишком медленно, то необходимо подождать, пока кусок станет доступным

В идеале, я бы не хотел полагаться на setTimeout() для ожидания на кусках. То, что я до сих пор близко, но не совсем то, что я ищу:

// container to hold chunks as they come in 
var chunkCollection = {}; 

// callback function for RTCDataChannel messages 
function onData(data) { 

    chunkCollection[data.chunkIndex] = data.chunk; 
    writeToFile(data.chunkIndex); 
} 

function writeToFile(chunkIndexToWrite) { 

    // if we have the next chunk, write it to the file 
    if (chunkCollection[chunkIndexToWrite]) { 
    var chunk = chunkCollection[chunkIndexToWrite]; 
    delete chunkCollection[chunkIndexToWrite]; 
    fileWriter.seek(chunk.offset); 
    fileWriter.write(chunk.blob); 
    } 
    else { 
    // we don't have the next chunk, so we have to wait 
    setTimeout(function() { 
     writeToFile(chunkIndexToWrite); 
    }, 100); 
    } 
} 

Проблема с этим состоит в том, что, если куски приходят слишком быстро, fileWriter не будет готов написать следующий кусок и будет выбросить исключение. Однако, если куски идут слишком медленно, установка правильного тайм-аута будет чрезвычайно сложной.

Кажется, что подход, основанный на событиях, будет работать лучше всего здесь. Одним из событий является сообщение данных, поступающее от RTCDataChannel. Другим событием является то, что fileWriter закончил писать и готов написать следующий фрагмент. Но кусок, который я застрял, - это то, как правильно подождать, когда кусок зайдет ...

Если браузер не занят написанием файла и просто сидит, ожидая, когда кусок появится , то браузер должен начать писать кусок, как только кусок будет доступен. Но я не могу понять, как это сделать без уродливого цикла setTimeout; Я не могу понять, как публиковать событие, в котором говорится, что нам больше не нужно ждать и продолжать писать.

Какая хорошая модель для этого?

ответ

1

Существует способ сделать это без тайм-аута, хотя он использует флаг, чтобы указать, что автор доступен, он все равно должен быть лучше, чем тайм-аут.

Я бы создал очередь, где куски данных будут сохранены, когда она поступит и будет использовать async fileWriter (тот, который выполняет обратный вызов, когда заканчивает запись в файл).

Как что:


var readyToWrite = true; 
var chunks = []; 

var onData = function(data) { 
    chunks.push(data); 
    if (readyToWrite) { 
     writeChunksToFile(chunks); 
    } 
}; 

var writeChunksToFile = function() { 
    if (chunks) { 
     readyToWrite = false; 
     fileWriter.write(chunks.shift(), function() { 
      writeChunksToFile(chunks); 
     }); 
    } else { 
     readyToWrite = true; 
    } 
}; 

Таким образом писатель не писать, пока куски станет пустым, то он уведомляет приемник данных (используя флаг), что он доступен, поэтому приемник данных (Ondata) знает, что он должен снова позвонить ему, когда будет получен следующий кусок. Если получатель данных получает данные, а писатель все еще записывает в файл, то он не будет называть его, он просто нажимает кусок на наш массив очередей, и писатель получит этот кусок, когда закончит его запись, потому что он называется рекурсивно.

Это простейший код, который мы могли бы написал с этим подходом, но вы можете сделать это «больше ООП» с ObserverPattern или «более функционален» с помощью Монада.

+0

...У меня такое ощущение, что здесь есть состояние гонки, но я постараюсь реализовать это правильно и посмотреть, как он работает. благодаря! – Hristo

+0

Не должно быть никаких условий гонки, потому что js однострочный, асинхронный. Порядок наших событий (* onData * и * fileWriteEnded *) в цикле событий не имеет значения. –

+0

правый. хорошая точка зрения. Сегодня я осуществлю это, и я дам вам знать, как это происходит. – Hristo

Смежные вопросы