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/
bufferedAmount
是 DataChannel
(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
此页面展示了如何通过 WebRTC 数据通道传输文件。
为了以可互操作的方式实现这一点,文件被分成块,然后通过数据通道传输。数据通道可靠且默认排序,非常适合文件传输。
虽然它不使用 peerjs,但它可以进行调整(以使用 peerjs)并且代码易于理解并且可以正常工作。
我正在使用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/
bufferedAmount
是 DataChannel
(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
此页面展示了如何通过 WebRTC 数据通道传输文件。
为了以可互操作的方式实现这一点,文件被分成块,然后通过数据通道传输。数据通道可靠且默认排序,非常适合文件传输。
虽然它不使用 peerjs,但它可以进行调整(以使用 peerjs)并且代码易于理解并且可以正常工作。