15

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

我正在尝试编写一个简单的点对点文件共享。我正在使用serialisation: "none"for PeerJSconnection DataChannel,因为我只是发送 pure 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 字节块的形式读取它ArrayBuffer(与 16x1024 没有区别),并且在读取每个块后 - 它通过 peer.send(ChunkArrayBuffer) 发送。

Recieverblob从每个收到的块中创建,在传输完成后创建一个完整的块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缓冲区的同时操作的某种限制?
Update1:​​这是我的PeerJS连接对象,DataChannel里面有对象:
Google Chrome 中的对象可视化

4

2 回答 2

8

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

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

我为自己编辑了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;
 }        
}

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

于 2015-05-31T21:48:02.887 回答
0

看看传输文件

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

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

虽然它不使用 peerjs,但它可以进行调整(使用 peerjs),并且代码易于遵循并且可以毫无问题地工作。

于 2021-10-17T18:15:55.553 回答