title: WebRTC - Failed to set remote answer sdp: Called in wrong state: STATE_INPROGRESS
body: <p>I'm following the example here: <a href="https://www.w3.org/TR/webrtc/#simple-peer-to-peer-example" rel="nofollow noreferrer">https://www.w3.org/TR/webrtc/#simple-peer-to-peer-example</a></p>
  
  <p>I've modified the code because I only need one-way streaming:</p>
  
  <pre><code>var configuration = null; //{ "iceServers": [{ "urls": "stuns:stun.example.org" }] };
  var peerConnection;
  
  var outboundPeerStream = null;
  var outboundPeerStreamSessionId = null;
  
  var createPeerConnection = function () {
      if (peerConnection)
          return;
  
      peerConnection = new RTCPeerConnection(configuration);
  
      // send any ice candidates to the other peer
      peerConnection.onicecandidate = function (event) {
          signalrModule.sendClientNotification(JSON.stringify({ "candidate": event.candidate }));
      };
  
      // let the "negotiationneeded" event trigger offer generation
      peerConnection.onnegotiationneeded = peerStreamingModule.sendOfferToPeers;
  
      // once remote track arrives, show it in the remote video element
      peerConnection.ontrack = function (event) {
          var inboundPeerStream = event.streams[0];
          remoteStreamHelper.pushStreamToDom(inboundPeerStream, foo);
      }
  }
  
  // this gets called either on negotiationNeeded and every 30s to ensure all peers have the offer from the stream originator
  peerStreamingModule.sendOfferToPeers = function () {
      peerConnection.createOffer().then(function (offer) {
          return peerConnection.setLocalDescription(offer);
      }).then(function () {
          // send the offer to the other peer
          signalrModule.sendClientNotification(JSON.stringify({ "desc": peerConnection.localDescription}));
      }).catch(logger.internalLog);
  };
  
  // this gets called by the stream originator when the stream is available to initiate streaming to peers
  peerStreamingModule.initializeWithStream = function (outboundStream, sessionId) {
      outboundPeerStream = outboundStream;
      outboundPeerStreamSessionId = sessionId;
      createPeerConnection();
      peerConnection.addStream(outboundStream);
      //peerStreamingModule.sendOfferToPeers(); I don't think I need this...
  }
  
  peerStreamingModule.handleP2PEvent = function (notification) {
      if (!peerConnection)
          createPeerConnection();
  
      if (notification.desc) {
          var desc = notification.desc;
          // if we get an offer, we need to reply with an answer
          if (desc.type == "offer") {
              peerConnection.setRemoteDescription(desc).then(function () {
                  return peerConnection.createAnswer();
              }).then(function (answer) {
                  return peerConnection.setLocalDescription(answer);
              }).then(function () {
                 signalrModule.sendClientNotification(JSON.stringify({ "desc": peerConnection.localDescription, "sessionId": sessionManager.thisSession().deviceSessionId() }), app.username());
              }).catch(logger.internalLog);
          } else if (desc.type == "answer") {
  
    peerConnection.setRemoteDescription(desc).catch(logger.internalLog);
          } else {
              logger.internalLog("Unsupported SDP type. Your code may differ here.");
          }
      } else
          pc.addIceCandidate(notification.candidate).catch(logger.internalLog);
  }
  </code></pre>
  
  <p>This seems to be working, but I'm stumped with two parts: </p>
  
  <p>1) <code>WebRTC - Failed to set remote answer sdp: Called in wrong state: STATE_INPROGRESS</code> - this is appearing in my logs from time to time - am I doing something wrong in the above that is causing this?</p>
  
  <p>2) Am I correctly implementing <code>sendOfferToPeers</code> and <code>initializeWithStream</code>?  I'm afraid that the <code>sendOfferToPeers</code> getting triggered on interval from the originator isn't how the spec is intended to be used; my goal is to ensure that all peers eventually receive an offer no matter when they join or whether or not they're facing connectivity issues that drop the original offer / negotiation.</p>