PeerJS/WebRTC 快速块传输时连接失败

PeerJS/WebRTC connection fails on rapid chunks transmittion

我正在使用PeerJS,但认为这个问题一般可以WebRTC,希望您能帮助我:

我正在尝试编写一个简单的点对点文件共享。我将 serialisation: "none" 用于 PeerJS 连接 DataChannel,因为我只发送纯 ArrayBuffers.
10mb 左右的文件一切都很好,但我在发送更大的文件 (30+ mb) 时遇到问题,例如在发送大约 10-20 个 900mb zip 文件的第一个块后,对等方之间的连接开始抛出 Connection is not open. You should listen for the "open" event before sending messages。 (在 Sender 一侧)

我的设置:

文件被拖放,Sender 使用 FileReader 以 64x1024 字节的块(与 16x1024 没有区别)读取它作为 ArrayBuffer 并且一旦每个块被读取 -它通过 peer.send(ChunkArrayBuffer).

发送

Reciever 从每个收到的块中创建 blob,传输完成后从中创建一个完整的 blob 并给用户一个 link。

我的对等连接设置:

   var con = peer.connect(peerid, {
        label: "file",
        reliable: true,
       serialization: "none"
   })

我的发送函数:

function sliceandsend(file, sendfunction) {
    var fileSize = file.size;
    var name = file.name;
    var mime = file.type;
    var chunkSize = 64 * 1024; // bytes
    var offset = 0;

 function readchunk() {
    var r = new FileReader();
    var blob = file.slice(offset, chunkSize + offset);
    r.onload = function(evt) {
        if (!evt.target.error) {
            offset += chunkSize;
            console.log("sending: " + (offset / fileSize) * 100 + "%");
            if (offset >= fileSize) {
                con.send(evt.target.result); ///final chunk
                console.log("Done reading file " + name + " " + mime);
                return;
            }
            else {                    
                con.send(evt.target.result);
            }               
        } else {
            console.log("Read error: " + evt.target.error);
            return; 
        }
        readchunk();
       };
        r.readAsArrayBuffer(blob);
    }
    readchunk();
  }

知道是什么原因造成的吗?

更新: 设置块传输之间的 50 毫秒超时有点帮助,900mb 文件加载达到 6%(而不是之前的 1-2%),然后开始抛出错误。也许是通过 datachannel 的同时操作的某种限制或溢出某种 datachannel 缓冲区?
Update1:​​ 这是我的 PeerJS 连接对象,其中包含 DataChannel 对象:

大家好消息!
这是 DataChannel 问题的缓冲区溢出,感谢这篇文章 http://viblast.com/blog/2015/2/25/webrtc-bufferedamount/

bufferedAmountDataChannel(DC) 对象的 属性,在最新的 Chrome 版本中,它以字节为单位显示当前的数据量缓冲区,当它超过 16MB 时 - DC 静默关闭。 因此,任何遇到此问题的人都需要在应用程序级别实施缓冲机制,它将监视此 属性 并在需要时阻止消息。另外,请注意,在 37 之前的 Chrome 版本中 相同的 属性 显示消息的数量(不是大小),并且更多的消息在 windows 下被破坏并显示 0,但是溢出时 v<37 未关闭 DC - 唯一的例外抛出,也可以被捕获以指示缓冲区溢出。

我自己编辑了peer.js未压缩的代码,在这里你可以在一个函数中看到两种方法(更多源代码你可以看https://github.com/peers/peerjs/blob/master/dist/peer.js#L217

DataConnection.prototype._trySend = function(msg) {
var self = this;
function buffering() {
    self._buffering = true;
    setTimeout(function() {
        // Try again.
        self._buffering = false;
        self._tryBuffer();
    }, 100);
    return false;
}
if (self._dc.bufferedAmount > 15728640) {
    return buffering(); ///custom buffering if > 15MB is buffered in DC 
} else {
    try {
        this._dc.send(msg);
    } catch (e) {
        return buffering(); ///custom buffering if DC exception caught
    }
    return true;
 }        
}

还在 PeerJS GitHub 上开了一个问题:https://github.com/peers/peerjs/issues/291

看看Transfer a file

此页面展示了如何通过 WebRTC 数据通道传输文件。

为了以可互操作的方式实现这一点,文件被分成块,然后通过数据通道传输。数据通道可靠且默认排序,非常适合文件传输。

虽然它不使用 peerjs,但它可以进行调整(以使用 peerjs)并且代码易于理解并且可以正常工作。