我正在使用 PeerJS,但认为这个问题一般与 WebRTC 有关,希望您能帮助我:
我正在尝试编写一个简单的点对点文件共享。我正在为 PeerJS 连接 DataChannel 使用 serialisation: "none",因为我只发送纯 ArrayBuffers .
文件大小约为 10mb,但我在发送更大的文件(30+ mb)时遇到问题,例如在发送大约 10-20 个 900mb zip 文件的第一个 block 后,对等方之间的连接开始抛出 Connection is not open。您应该在发送消息之前监听“打开”事件。 (在 Sender 端)
我的设置:
文件被拖放,Sender 使用 FileReader 以 64x1024 字节的 block (与 16x1024 没有区别)和作为 ArrayBuffer 读取它一旦读取每个 block - 它就会通过 peer.send(ChunkArrayBuffer) 发送。
Reciever 从每个收到的 block 中创建 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();
}
知道是什么原因造成的吗?
更新:在 block 传输之间设置 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>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
关于javascript - PeerJS/WebRTC 连接在快速 block 传输时失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30494011/
我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere
我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以
我在理解Enumerator.new方法的工作原理时遇到了一些困难。假设文档中的示例:fib=Enumerator.newdo|y|a=b=1loopdoy[1,1,2,3,5,8,13,21,34,55]循环中断条件在哪里,它如何知道循环应该迭代多少次(因为它没有任何明确的中断条件并且看起来像无限循环)? 最佳答案 Enumerator使用Fibers在内部。您的示例等效于:require'fiber'fiber=Fiber.newdoa=b=1loopdoFiber.yieldaa,b=b,a+bendend10.times.m
我使用的是Firefox版本36.0.1和Selenium-Webdrivergem版本2.45.0。我能够创建Firefox实例,但无法使用脚本继续进行进一步的操作无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055)错误。有人能帮帮我吗? 最佳答案 我遇到了同样的问题。降级到firefoxv33后一切正常。您可以找到旧版本here 关于ruby-无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055),我们在StackOverflow上找到一个类
我已经构建了一些serverspec代码来在多个主机上运行一组测试。问题是当任何测试失败时,测试会在当前主机停止。即使测试失败,我也希望它继续在所有主机上运行。Rakefile:namespace:specdotask:all=>hosts.map{|h|'spec:'+h.split('.')[0]}hosts.eachdo|host|begindesc"Runserverspecto#{host}"RSpec::Core::RakeTask.new(host)do|t|ENV['TARGET_HOST']=hostt.pattern="spec/cfengine3/*_spec.r
我没有理解以下行为(另请参阅inthisSOthread):defdef_testputs'def_test.in'yieldifblock_given?puts'def_test.out'enddef_testdoputs'def_testok'endblock_test=procdo|&block|puts'block_test.in'block.callifblockputs'block_test.out'endblock_test.calldoputs'block_test'endproc_test=procdoputs'proc_test.in'yieldifblock_gi
我正在尝试在Rails上安装ruby,到目前为止一切都已安装,但是当我尝试使用rakedb:create创建数据库时,我收到一个奇怪的错误:dyld:lazysymbolbindingfailed:Symbolnotfound:_mysql_get_client_infoReferencedfrom:/Library/Ruby/Gems/1.8/gems/mysql2-0.3.11/lib/mysql2/mysql2.bundleExpectedin:flatnamespacedyld:Symbolnotfound:_mysql_get_client_infoReferencedf
我需要尝试一些AES片段。我有一些密文c和一个keyk。密文已使用AES-CBC加密,并在前面加上IV。不存在填充,纯文本的长度是16的倍数。所以我这样做:aes=OpenSSL::Cipher::Cipher.new("AES-128-CCB")aes.decryptaes.key=kaes.iv=c[0..15]aes.update(c[16..63])+aes.final它工作得很好。现在我需要手动执行CBC模式,所以我需要单个block的“普通”AES解密。我正在尝试这个:aes=OpenSSL::Cipher::Cipher.new("AES-128-ECB")aes.dec
我需要一个非常简单的字符串验证器来显示第一个符号与所需格式不对应的位置。我想使用正则表达式,但在这种情况下,我必须找到与表达式相对应的字符串停止的位置,但我找不到可以做到这一点的方法。(这一定是一种相当简单的方法……也许没有?)例如,如果我有正则表达式:/^Q+E+R+$/带字符串:"QQQQEEE2ER"期望的结果应该是7 最佳答案 一个想法:你可以做的是标记你的模式并用可选的嵌套捕获组编写它:^(Q+(E+(R+($)?)?)?)?然后你只需要计算你获得的捕获组的数量就可以知道正则表达式引擎在模式中停止的位置,你可以确定匹配结束
我在使用自定义RailsFormBuilder时遇到了问题,从昨天晚上开始我就发疯了。基本上我想对我的构建器方法之一有一个可选block,以便我可以在我的主要content_tag中显示其他内容。:defform_field(method,&block)content_tag(:div,class:'field')doconcatlabel(method,"Label#{method}")concattext_field(method)capture(&block)ifblock_given?endend当我在我的一个Slim模板中调用该方法时,如下所示:=f.form_field:e