如何重置Chrome中的WebRTC组件状态 – 无需重新加载页面 – 当它们被踢入无效状态时如何?有关我如何复制此状态的详细信息,请参阅下文,以及为什么我这样问:
问题描述:
尝试在拨打电话时设置Ice Candidates时,我在Chrome 35 / node-webkit 0.10.0中收到以下错误:
Failed to execute ‘addIceCandidate’ on ‘RTCPeerConnection’: The ICE candidate could not be added.
现在,我知道为什么会这样.我正在制作一个可以处理一些普通用户滥用的ROBUST WebRTC应用程序.要复制这种状态,我基本上必须进行一些WebRTC调用然后快速杀死它们然后立即尝试另一个调用.我猜这必须将PeerConnection和其他组件放到一个不同的状态,在那里它会发生B,但我重新开始用A.这可以通过以下错误消息证明:
Failed to set session description: Failed to set remote answer sdp: Called in wrong state: STATE_INIT
现在,我们在互联网上看到的大多数WebRTC演示(如http://apprtc.appspot.com)都是无状态的,浏览器经常刷新,导致重置DOM状态.因此,对于那些开发人员来说,答案很简单.只需重新加载页面并将其称为好.
目前,我必须在DOM进入此状态时重新加载应用程序.但是,这不是一个可接受的解决方案,因为我正在构建单页应用程序,而不是网站,
我想知道是否有办法调用API来告诉它重置抛出这些错误的状态?
一些故障排除步骤
我尝试了以下命令,从node-webkit(Chrome 35)中的JavaScript控制台,看看我是否可以手动重置PeerConnection的状态,但它没有帮助:
var properties = {}; properties.pcConfig = { "iceServers": [{ "url": "stun:stun.l.google.com:19302" }] }; properties.pcConstraints = { "optional": [] }; peerConn = new RTCPeerConnection(properties.pcConfig,properties.pcConstraints); peerConn.close();
peerConn.signalingState --> "closed" peerConn.iceConnectionState --> "closed" peerConn.iceGatheringState --> "complete"
解决方法
请注意,关闭状态是最终状态,应删除关闭的对等连接,因为它无法重用.
在您的情况下,删除原始对等连接并创建一个新连接是必须的,但还不够.您需要重新发起握手,并确保不会捕获和使用针对原始对等连接的消息,并由其他对等连接使用.多方客户具有相同的设计问题.解决它的一种方法,也是解决眩光问题的方法是添加到“提供”,“回答”,“候选”消息,您可以离线交换“原点”和可能的“目标”字段.您必须自己生成ID,因为默认情况下对等连接对象没有唯一ID.
这是正常的舞蹈(有涓流ICE):
> A即将上线,创建对等连接并在地图中将其疼痛
在索引A_0
> B上线,与B_0相同(确保ID是唯一的)
> A正在呼叫B.
> A发送报价,附加字段“origin”:“A_0”和“target”:“B_0”
> B接收报价,setLocalDescription(开始ICE收集),发送原点答案:B_0,目标:A_0,完成.
>接收答案,设置本地描述(开始ICE收集),完成.
>正在与目标和原始字段进行适当交换的ICE候选人.
现在有问题的情况:
> A在收到B的答案之前删除其A_0对等连接.
> B发送A_0的答案和ICE候选,由A作为A_0丢弃,不存在.
> A用A_1重新开始舞蹈
眩光案例:
> A和B同时发送报价
>比较ID并根据可重现的任意规则选择一个(数字越大,字符串越大,使用字母顺序……)
请注意,此设计还允许多方调用,因为每个调用将由映射隔离,并由消息传递逻辑路由.
function handleGenericMsg(msg){ if( msg.origin === username ) { trace( 'MAIN - [' + username + '] Ignoring self message: ' + msg.type + '.' ); return; } switch(msg.type){ case 'offer': offerHandler(msg); break; default: trace( 'MAIN - [' + targetMid + '] Unsupported message received: ' + JSON.stringify(msg)); break; } }; function offerHandler( msg ){ var targetMid = msg.origin; offer = new RTCSessionDescription(msg); trace( 'PC - [' + targetMid + '] Received offer.' ) var pc = peerConnections[ targetMid ]; if( !pc ) { openPeer( targetMid,false ); pc = peerConnections[ targetMid ]; } else { // we already had a PC,let's reuse it } pc.setRemoteDescription( offer ); doAnswer( targetMid ); };