【问题标题】:PeerJS/WebRTC connection fails on rapid chunks transmittionPeerJS/WebRTC 连接在快速块传输时失败
【发布时间】:2015-08-10 05:17:44
【问题描述】:

我用的是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 将其读取为ArrayBuffer,以 64x1024 字节的块(与 16x1024 没有区别)并且一旦读取每个块 - 它就通过 peer.send(ChunkArrayBuffer )。

Reciever 从每个收到的块中创建blob,在传输完成后从这些块中创建一个完整的blob 并提供给用户的链接。

我的对等连接设置:

   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();
  }

有什么想法会导致这种情况吗?

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

【问题讨论】:

  • 我在某些时候遇到过同样的问题,但现在没有了。我的代码在 github 结束,但用 dart 编写。也许它有帮助!我将{'ordered': true, 'reliable': true} 添加到createDataChannel 也许有帮助?
  • @Robert 遗憾的是这并没有帮助,“有序”和“可靠”在我的 DataChannel 对象中已经是真的 peerjs 连接对象。我现在将我的连接对象添加到问题中,你能把你的扔在这里,所以我可以比较两个吗?
  • 我的 github 代码有一个链接。我没有使用 peerjs,所以在这里我不能真正帮助你:( 对我来说,FileReader 需要大约 25-50 毫秒来将 blob 转换为 bytearray,这似乎足以让它对我有用。
  • @Robert 我的意思是在运行时创建的连接对象,当您连接到另一个对等点时,您正在使用该对等点发送消息。当然,如果您现在可以轻松访问它。老实说,设置 localhost 来运行你的代码来查看一个对象有点麻烦。
  • DataChannel 看起来一模一样。

标签: javascript webrtc file-sharing chunks peerjs


【解决方案1】:

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

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

我为自己在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

【讨论】:

    【解决方案2】:

    看看Transfer a file

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

    为了以可互操作的方式完成此任务,文件被分成块,然后通过数据通道传输。默认情况下,数据通道可靠且有序,非常适合文件传输。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-15
      • 2019-07-19
      • 1970-01-01
      • 2010-09-06
      • 2014-06-18
      • 1970-01-01
      • 2015-06-23
      • 2020-07-13
      相关资源
      最近更新 更多