mdn / samples-server

MDN samples server; used for samples that can't be hosted in-place on MDN, plus back-end server-side code for samples that need it.
https://developer.mozilla.org/
Creative Commons Zero v1.0 Universal
958 stars 927 forks source link

onnegotiationneeded event fired twice in Chrome #57

Open iyeldinov opened 6 years ago

iyeldinov commented 6 years ago

sample tested in Chrome 68 - doesn't work without adapter:

Failed to set remote offer sdp: Called in wrong state: kHaveLocalOffer

with adapter:

PeerConnection cannot create an answer in a state other than have-remote-offer or have-local-pranswer.

but in FF works just fine.

I've figured out that Chrome fires onnegotiationneeded on each track added while FF fires it once. Firing twice results into sending offer twice

How to workaround that issue, does anybody knows?

iyeldinov commented 6 years ago

Here is bug https://bugs.chromium.org/p/chromium/issues/detail?id=740501

iyeldinov commented 6 years ago

ONN twice issue can be fixed with a re-entrancy guard:

pc.onnegotiationneeded = async e => {
  if (pc._negotiating == true) return;
  pc._negotiating = true;
  try {
    return cb(e);
  } finally {
    pc._negotiating = false;
  }
}

So the updated code from tutorial will look like (ah, and it is async/await instead of promises too :) )

async function handleNegotiationNeededEvent() {
    if (myPeerConnection._negotiating == true) return;
    log("*** Negotiation needed");
    myPeerConnection._negotiating = true;
    try {
        log("---> Creating offer");
        const offer = await myPeerConnection.createOffer();

        log("---> Creating new description object to send to remote peer");
        await myPeerConnection.setLocalDescription(offer);

        log("---> Sending offer to remote peer");
        sendToServer({
            name: myUsername,
            target: targetUsername,
            type: "video-offer",
            sdp: myPeerConnection.localDescription
        });
    } catch (e) {
        reportError(e)
    } finally {
        myPeerConnection._negotiating = false;
    }
}
deepinder10 commented 6 years ago

Solved that error but now this one. Failed to execute 'addTrack' on 'RTCPeerConnection': A sender already exists for the track.

superddr commented 5 years ago

yes, when two addTrack() are used , two onnegotiationneeded events will be fired. Still dont know what to do now

sumitgupta07 commented 4 years ago

I am having similar issue. Anyone able to figure this out. My scenarios:

  1. One user (say User A) connects with only audio track. Other user (say User B) connects with both audio and video tracks.
  2. If User B is offerer, connection is established perfectly and User A can display User B video and both are able to talk to each other.
  3. If User B is answerer and User it has to send 2 tracks, in which case it is triggering onnegotiationneeded event. Which in-turn starting another session of offer-answer session. Which is not desired.
  4. If I discard this extra onnegotiationneeded event, User A cannot see User B video. But only able to talk to each other.

Let me know if there is any solution for such solution. I am trying for last more than 1 week.

Thanks