4

I'm following the example here: https://www.w3.org/TR/webrtc/#simple-peer-to-peer-example

I've modified the code because I only need one-way streaming:

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);
}

This seems to be working, but I'm stumped with two parts:

1) WebRTC - Failed to set remote answer sdp: Called in wrong state: STATE_INPROGRESS - this is appearing in my logs from time to time - am I doing something wrong in the above that is causing this?

2) Am I correctly implementing sendOfferToPeers and initializeWithStream? I'm afraid that the sendOfferToPeers 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.

SB2055
  • 12,272
  • 32
  • 97
  • 202

1 Answers1

6

// this gets called either on negotiationNeeded and every 30s to ensure all peers have the offer

You can't send the same offer to multiple peers. It's peer-to-peer, not peer-to-peers. One-to-many requires at minimum a connection per participant, and probably a media server to scale.

Also, SDP is not for discovery. The offer/answer exchange is a fragile state-machine negotiation between two end-points only, to set up a single connection.

You should solve who's connecting with whom ahead of establishing the WebRTC connection.

jib
  • 40,579
  • 17
  • 100
  • 158
  • Thank you for this. I just updated my implementation to create two connection per "peer pair". This seems to be working to some extent but I'm now facing an issue with multiple peers - would appreciate any inputs you may have: https://stackoverflow.com/questions/44157738/webrtc-sharing-one-stream-with-multiple-peers – SB2055 May 24 '17 at 12:13