Как я могу подключить более двух пиров? - PullRequest
1 голос
/ 04 февраля 2020

Я хочу иметь возможность подключать произвольное количество пиров, используя WebRT C, и разрешать им общаться друг с другом по каналам данных. К настоящему времени 2 локальных пира в 2 вкладках уже могут успешно подключиться и отправить «Привет!» друг к другу:

<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>

Вывод на консоль - это на обеих вкладках:

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

Вкл. localhost:1234 У меня работает сервер сигнализации, позволяющий подключить WebSocket и обновить соединение, и всякий раз, когда сообщение отправляется в WebSocket, сервер просто отправляет это сообщение всем другим подключенным WebSockets, кроме WebSocket, который отправил сообщение.

Но теперь я не уверен, как go о подключении более 2 пэров. Если я открываю третью вкладку и пытаюсь подключиться, я получаю сообщение об ошибке в консоли всех вкладок: InvalidStateError: Cannot set remote answer in state stable и соединения прерываются.

1 Ответ

1 голос
/ 05 февраля 2020

WebRT C поддерживает только соединения 1: 1. Для каждого нового партнера, который хочет присоединиться ко мне sh, вам нужно создать еще одно PeerConnection. То, что вы пытаетесь реализовать, обычно называется Mesh Topology. Я бы также посмотрел на SFU, поскольку при масштабировании вы можете столкнуться с ограничениями пропускной способности / ЦП.

В вашем коде сигнализации вам, вероятно, понадобится уникальный идентификатор некоторого вида, а затем отправлять сообщения в различные PeerConnections. Топология будет выглядеть следующим образом.

Mesh Topology

...