WebRTC 数据通道缓冲满

WebRTC DataChannel buffered full

首先,我希望你理解我的英语不好。

对于文件传输,在 Mesh 拓扑中,在 Chrome,

当缓冲量为 16MB 时,通道将关闭并显示错误消息。

"Uncaught NetworkError: Failed to execute 'send' on 'RTCDataChannel': Could not send data"
(它在 chrome,而不是 firefox。)

如何发送文件(大于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];
},

我试图解决这个问题。
我只是使用 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);
            }
        }
    },

你有更好的东西吗?