1

最初に、私が英語が苦手であることを理解していただければ幸いです。

ファイル転送の場合、メッシュ トポロジで、Chrome で、

バッファ量が 16MB の場合、チャネルはエラー メッセージで閉じられます。

「Uncaught NetworkError: Failed to execute 'send' on 'RTCDataChannel': Could not send data」
(Firefox ではなく Chrome にあります)

16MB以上のファイルを送るには?

fileWorker.js

var chunkSize = 16384;
onmessage = function(event) {
    var file = event.data[0],
        callbackId = event.data[1],
        totalSize = file.size,
        chunks = [],
        curSize = 0,
        reader,
        chunk;

    if (!FileReaderSync) {
        reader = new FileReader();
        reader.onload = function(event) {
            console.log('chunking...');
            chunks.push(event.target.result);
            curSize += chunkSize;
            slice();
        };
        slice();
    } else {
        reader = new FileReaderSync();
        while (curSize < totalSize) {
            console.log('chunking...');
            chunk = file.slice(curSize, curSize + chunkSize);
            chunks.push(reader.readAsArrayBuffer(chunk));
            curSize += chunkSize;
        }
        postMessage([chunks, file.name, callbackId]);
    }

    function slice() {
        if (curSize > totalSize) {
            postMessage([chunks, file.name, callbackId]);
        } else {
            chunk = file.slice(curSize, curSize + chunkSize);
            reader.readAsArrayBuffer(chunk);
        }
    }
};

ファイル送信者

_fileToPeers: function(chunks, fileName, progressCallbackId) {
    var callback = callbacks[progressCallbackId],
        chunkCount,
        peerCount = 0;

    objForEach(this.peers, function(peer) {
        var channel = peer.fileChannel;
        peerCount += 1;

        if (channel) {
            chunkCount = 0;
            chunks.forEach(function(chunk) {
                channel.send(chunk);
                chunkCount += 1;
                console.log('sending...');         // abnormal works!  
                callback(peerCount, chunkCount);   // abnormal works!
            });
            channel.send(['end', fileName].join(','));
        }
    });
    delete callbacks[progressCallbackId];
},
4

1 に答える 1

1

この問題を解決しようとしました。
setTimeout で再帰関数呼び出しを使用するだけです。

コード

    _fileToPeers: function(chunks, fileName, progressCallbackId) {
        var callback = callbacks[progressCallbackId];

        objForEach(this.peers, function(peer) {
            var channel = peer.fileChannel;
            if (channel && !channel.using) {
                channel.using = true;
                this._chunksInChannel(chunks, 0, fileName, channel, callback);
            }
        }, this);
        delete callbacks[progressCallbackId];
    },

    _chunksInChannel: function(chunks, chunkIdx, fileName, channel, callback) {
        var length = chunks.length,
            doNext = chunkIdx < length;

        while (doNext) {
            if (channel.bufferedAmount > CHANNEL_BUFFER_MAX) {
                setTimeout(function () {
                    this._chunksInChannel(chunks, chunkIdx, fileName, channel, callback);
                }.bind(this), 500);
                doNext = false;
            } else {
                channel.send(chunks[chunkIdx]);
                chunkIdx += 1;
                if (chunkIdx === length) {
                    channel.send(['end', fileName].join(','));
                    doNext = false;
                    channel.using = false;
                }
                callback(chunkIdx);
            }
        }
    },

もっといいものありませんか?

于 2015-08-27T07:16:58.280 に答える