How can I reset WebRTC state in Chrome / node-webkit without refreshing the page?

Question:

How to reset the state of WebRTC components in Chrome - without reloading the page - when they are kicked out of an invalid state? For more information on how I replicate this state, and why I ask about it, see below:

Description of the problem:

I get the following error in Chrome 35 / node -webkit 0.10.0 when trying to install Ice Candidates when making a call:

Failed to execute 'addIceCandidate' in 'RTCPeerConnection': ICE candidate could not be added.

Now I know why this is happening. I am working on a ROBUST WebRTC application that can handle some of the normal issues. To reproduce this state, I basically have to make a couple of WebRTC calls, and then quickly kill them, and then try another call right away. I assume that this should cause PeerConnection and other components to switch to a different state, where B is expected to wait, but I start over with A. The following error message indicates this:

Failed to set session description: Failed to set remote sdp response: Called in the wrong state: STATE_INIT

Now, most of the WebRTC demos we see on the Internet, such as http://apprtc.appspot.com , are stateless, and the browser is frequently updated, which causes the DOM to reset. So for those developers, the answer is simple. Just reload the page and name it well.

Currently, I have to restart the application when the DOM enters this state. However, this is not an acceptable solution, as I am creating a one-page application, not a website,

I am wondering if there is a way to make an API call to inform it of a reset state that it is throwing these errors?

Some troubleshooting steps:

I tried the following: from the JavaScript console in node -webkit (Chrome 35) to find out if I can manually reset the state of PeerConnection, but this does not help:

var properties = {}; properties.pcConfig = { "iceServers": [{ "url": "stun:stun.l.google.com:19302" }] }; properties.pcConstraints = { "optional": [] }; peerConn = new RTCPeerConnection(properties.pcConfig, properties.pcConstraints); peerConn.close(); 

Here is the output of some peerConnection properties:

 peerConn.signalingState --> "closed" peerConn.iceConnectionState --> "closed" peerConn.iceGatheringState --> "complete" 
+7
javascript google-chrome chromium webrtc node-webkit
source share
1 answer

It is assumed that you can change rollback . This can happen only when the roles do not change, i.e. When the caller in the first call is still the caller in subsequent calls and may not be acceptable in your case, because the error message you receive is related to receiving peer-to-peer responses before issuing the offer (i.e. mismatch between the caller / called subscriber).

Note that the closed states are final and the closed peer connection must be deleted because it cannot be reused.

In your case, removing the original peer and creating a new one is mandatory, but not enough. You will need to resume the handshake and make sure that messages aimed at the original peer are not captured or used by other peers. Multiparty customers have the same design problem. One of the ways to solve it, as well as to solve the problem of glare, is to add to the messages "proposal", "answer", "candidate", which you exchange offline with a "source" and potentially "target". You must generate the identifiers yourself, because by default there is no unique identifier for a peer.

here is a normal dance (with flowing ICE):

  • A goes online, creates a peer-to-peer connection and hurts him on the map at index A_0
  • B goes online, as above, with B_0 (make sure the identifiers are unique)
  • A calls B
    • Send a sentence with the additional field "origin": "A_0" and "target": "B_0"
    • B get an offer, setLocalDescription (starts collecting ICE), send a response indicating the source: B_0, target: A_0, Done.
    • Get an answer, set a local description (ICE collection begins), Done.
    • ICE candidates exchange with the appropriate field of purpose and origin.

now problematic case:

  • A deletes its peer connection A_0 before accepting the answer B.
  • B sends ICE responses and candidates for A_0, which are discarded by A since A_0 does not exist.
  • Restart the dance with A_1

glare:

  • A and B send each other at the same time.
  • compare identifiers and choose one in accordance with a reproducible arbitrary rule (larger number, large string, use an alphabetical sequence, ....)

Note that this design also allows for multi-party calls, as each call will be isolated by a card and routed by the messaging logic.

 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 reuse it } pc.setRemoteDescription( offer ); doAnswer( targetMid ); }; 
+2
source share

All Articles