Буферизация WebRTC DataChannel заполнена

Во-первых, я надеюсь, вы понимаете, что я не силен в английском.

Для передачи файлов в топологии Mesh в Chrome,

Когда размер буфера составляет 16 МБ, канал закрывается с сообщением об ошибке.

«Uncaught NetworkError: не удалось выполнить «отправить» на «RTCDataChannel»: не удалось отправить данные»
(это в Chrome, а не в Firefox.)

Как отправить файл (более 16 МБ)?

файлWorker.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];
},

person Community    schedule 27.08.2015    source источник
comment
Просто подождите, пока буфер не будет заполнен, тогда вы сможете успешно отправить данные.   -  person ritian zheng    schedule 28.06.2017


Ответы (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);
            }
        }
    },

Нет ли у вас чего-нибудь получше?

person Community    schedule 27.08.2015