0

I'm trying to make a random system of connections. I have a button that initiates a connection and also looks for new peer for a new automatic call. But it is intermittent, sometimes it works perfect, sometimes I do not know anymore.

Backend - server.js

    /** successful connection */
wss.on('connection', function (client) {
    console.log("A new WebSocket client was connected.");
    /** incomming message */
    client.on('message', function (message) {
      /** broadcast message to all clients */
        var obj = JSON.parse(message);
        if("callState" in obj) {
          // New client, add it to the id/client object
          // client.set('call_state') = 1
          console.log("Recebeu mensagem!!!");
        }else if("sdp" in obj || "ice" in obj) {
          wss.broadcast(message, client);
        }else{
          console.log("Recebeu: "+message);
        }
    });
});

// broadcasting the message to all WebSocket clients.
wss.broadcast = function (data, exclude) {
  console.log("Broadcasting message to all " + this.clients.length + " WebSocket clients.");
  for(var i in this.clients) {
    client = this.clients[i];
    // don't send the message to the sender...
    if (client === exclude) continue;
    if (client.readyState === client.OPEN) client.send(data);
    else console.error('Error: the client state is ' + client.readyState);
  }
};

Frontend - webrtc.js

    /** button START */
function start(isCaller) {
    peerConnection = new RTCPeerConnection(peerConnectionConfig);
    peerConnection.onicecandidate = gotIceCandidate;
    peerConnection.addStream(localStream);

    if ('ontrack' in peerConnection) {
        // WebRTC Spec, Firefox
        peerConnection.ontrack = ontrack
     } else {
        // Chrome, etc. This can be removed once all browsers support `ontrack`
        peerConnection.onaddstream = gotRemoteStream
     }

    if(isCaller) {
        peerConnection.createOffer().then(createdDescription).catch(errorHandler);
    }
}

function gotMessageFromServer(message) {
    if(!peerConnection) start(false);

    var signal = JSON.parse(message.data);

    // Ignore messages from ourself
    if(signal.uuid == uuid) return;

    if(signal.sdp) {
        peerConnection.setRemoteDescription(new RTCSessionDescription(signal.sdp)).then(function() {
            // Only create answers in response to offers
            if(signal.sdp.type == 'offer') {
                peerConnection.createAnswer().then(createdDescription).catch(errorHandler);
            }
        }).catch(errorHandler);
    } else if(signal.ice) {
        peerConnection.addIceCandidate(new RTCIceCandidate(signal.ice)).catch(errorHandler);
    }
}

In the server log shows that every time I press the "Start" button it log 1 SDP message and 14 ICE messages


EDIT: Including error

When I call the "start" button for the first time, everything works. However, in the following calls sometimes only the audio feature remains and at other times without a new connection.

I was able to reproduce an error after clicking "Start" several times: DOMException [InvalidStateError: "Cannot set remote answer in state stable" code: 11 nsresult: 0x8053000b]

I have a local server running on: https://luisdemarchi.aplicativo.info:8091

luisdemarchi
  • 1,402
  • 19
  • 29
  • What do you mean "random system of connections"? Please explain desired behavior, what's working and what's not, and what error messages you get. – jib Jan 12 '17 at 02:28
  • @jib I perform a test connecting the service on 6 different computers. When you click the "Start" button, it searches for a new candidate and opens a new connection, varying between the connections. But sometimes it does not connect to any machine and sometimes only the audio works (leaving the remote video all black). All machines have a configuration and a browser. No apparent error. The idea is to make a video chat with strangers, with a "Next" button (to make a connection with another randomly). PS: Translating with help from Google. – luisdemarchi Jan 12 '17 at 13:04
  • I don't know what you mean by "searches for a new candidate". Do you mean a potential peer, or an ICE candidate? Those are totally different things. Taking a step back, in order for two peers to reliably establish a connection, they need to agree on their role ahead of time (which one is to be the offerer and which one is to be the answerer). Therefore, you need to solve discovery of whom you're going to connect with *before* engaging in WebRTC negotiation. Otherwise, the two peers may be in incompatible states, and negotiation fails. – jib Jan 12 '17 at 14:48
  • @jib Potential peer. Each time a user presses the button "start", it re-synchronises and falls on the server's broadcast, which sends the connection data to everyone who is in the "Open" status, excluding the account itself. With this the magic happens according would like and randomly initiates a connection with another user (random users). But if you keep pressing on start, you "start" not having video or not sync with anyone. – luisdemarchi Jan 12 '17 at 17:28
  • @jib Includes an error line and the link from my computer if you can check. – luisdemarchi Jan 12 '17 at 18:13
  • And it works when you don't do this randomization? That suggests a bug in your pairing code. The error you show (which I [already answered about](http://stackoverflow.com/a/41580476/918910)) suggests same: that your chosen peers are not in agreement about their role in establishing a connection; both [sending offers](http://stackoverflow.com/questions/41531279/send-offers-with-webrtc-only/41540144). – jib Jan 13 '17 at 01:41
  • @jib Thank you so much for the help you have been giving. I have a question: When a user logs in, he sends an ICE by broadcast, then when he creates an offer, he again sends a broadcast SDP. But I'm guessing that this second call should be redirected only to one person, who will need to do this logic on the server side. no? – luisdemarchi Jan 13 '17 at 13:40
  • WebRTC is peer-to-peer. *Nothing* should be broadcast. An ICE candidate is not a "potential peer", rather a low-level detail of SDP negotiation between two peers that are in the middle of establishing a connection. It's called a "candidate" only because there may be multiple ways of reaching the same peer, for the other side to pick from. Signaling (trickling) of ICE candidates must always be signaled *after* an offer or answer is signaled. That they're signaled separately from the offer/answr at all, is just an optimization meant to speed up connection establishment. – jib Jan 13 '17 at 14:23
  • 1
    @jib Now I understand better. I followed the [WebRTC Tutorial](https://www.tutorialspoint.com/webrtc/index.htm) tutorial from end to end and it's perfect. Thank you very much for your explanations. – luisdemarchi Jan 13 '17 at 21:28

0 Answers0