user12374797
user12374797

Reputation:

How can I connect more than 2 peers?

I want to be able to connect an arbitrary amount of peers using WebRTC and allow them to communicate with each other using data channels. So far 2 local peers in 2 tabs can already sucessfully connect and send "Hello!" to each other:

<meta charset="utf-8">
<script>
const server = new WebSocket('ws://localhost:1234');

let peer;
let send_channel;

server.onmessage = function(event) {
  const data = JSON.parse(event.data);
  if(data.type == 'offer') {
    peer.setRemoteDescription(new RTCSessionDescription(data));
    peer.createAnswer()
      .then(answer => peer.setLocalDescription(answer))
      .then(() => server.send(JSON.stringify(peer.localDescription)));
  } else if(data.type == 'answer') {
    peer.setRemoteDescription(new RTCSessionDescription(data));
  } else if(data.type == 'candidate') {
    peer.addIceCandidate(new RTCIceCandidate({
      candidate: data.candidate,
      sdpMid: data.sdpMid
    }));
  }
}

server.onopen = function(event) {
  peer = new RTCPeerConnection();
  send_channel = peer.createDataChannel('channel');

  send_channel.onopen = function(event) {
    console.log('Send channel opened:', event);
  }
  send_channel.onclose = function(event) {
    console.log('Send channel closed:', event);
  }

  peer.ondatachannel = function(event) {
    event.channel.onopen = function(event) {
      console.log('Receive channel opened:', event);
      send_channel.send('Hello!');
    }
    event.channel.onclose = function(event) {
      console.log('Receive channel closed:', event);
    }
    event.channel.onmessage = function(event) {
      console.log('Message received:', event);
    }
  }

  peer.onicecandidate = function(event) {
    if (event.candidate) {
      server.send(JSON.stringify(
        {
          type: 'candidate',
          candidate: event.candidate.candidate,
          sdpMid: event.candidate.sdpMid
        }
      ));
    }
  };

  const offer = peer.createOffer()
    .then(offer => peer.setLocalDescription(offer))
    .then(() => server.send(JSON.stringify(peer.localDescription)));
}
</script>

Console output is this in both tabs:

Send channel opened: 
open { target: RTCDataChannel, … }
Receive channel opened: 
open { target: RTCDataChannel, … }
Message received: 
message { data: "Hello!", … }

On localhost:1234 I have a signaling server running that lets the WebSocket connect and upgrades the connection and whenever a message is sent to the WebSocket, the server simply sends that message to all other connected WebSockets, except for the WebSocket that sent the message.

But now I'm not sure how to go about connecting more than 2 peers. If I open a third tab and it tries to connect, I get this error message in the console of all tabs: InvalidStateError: Cannot set remote answer in state stable and the connections are disrupted.

Upvotes: 3

Views: 696

Answers (1)

Sean DuBois
Sean DuBois

Reputation: 4252

WebRTC only supports 1:1 connections. For each new peer that wants to join your mesh you will need to create another PeerConnection. What you are trying to implement is commonly known as a Mesh Topology I would also look into an SFU, as you scale you might hit bandwidth/CPU limits.

In your signaling code you will probably need to have a unique ID of some sort and then dispatch messages to distinct PeerConnections. The topology will look like this.

Mesh Topology

Upvotes: 4

Related Questions