3

WebRTC 経由でファイルを転送しようとしていますが、データが入ってきたときにデータを書き込むための適切なパターンを見つけるのに苦労しています。利用可能になったらチャンク。これは次の 2 つのことを意味します。

  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、次のチャンクを書き込む準備ができておらず、例外がスローされることです。ただし、チャンクの受信が遅すぎると、正しいタイムアウトを設定するのが非常に難しくなります。

ここでは、イベント駆動型のアプローチが最適に機能するようです。1 つのイベントは、 から着信するデータ メッセージRTCDataChannelです。もう 1 つのイベントは、fileWriter書き込みが完了し、次のチャンクを書き込む準備ができていることです。しかし、私が立ち往生している部分は、チャンクが入ってくるのを適切に待つ方法です...

ブラウザがファイルへの書き込みで忙しくなく、チャンクが入ってくるのを待っているだけの場合、ブラウザはチャンクが利用可能になり次第、チャンクの書き込みを開始する必要があります。setTimeoutしかし、いループなしでこれを行う方法がわかりません。もう待つ必要がなく、書き続けることができるというイベントを公開する方法がわかりません。

これを行うための良いパターンは何ですか?

4

1 に答える 1

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を使用して「より OOP」にするか、 Monadを使用して「より機能的に」することができます。

于 2015-05-27T10:46:08.867 に答える