WebRTC - это библиотека с открытым исходным кодом для установления прямых одноранговых соединений между 2 клиентами браузера для передачи видео и аудиопотоков в реальном времени, а также данных через канал данных.

Многие из доступных руководств иллюстрируют только одно соединение WebRTC на клиента или жестко запрограммированные множественные соединения, например peer1, peer2, peer3 и т. Д. Однако возникает вопрос, как динамически создавать и управлять несколькими RTCPeerConnections для каждого клиента. Я столкнулся с этим препятствием при создании библиотеки JavaScript, которая помогла разработчикам легко объединить несколько потоковых трансляций в реальном времени на одном дисплее.

В качестве контекста библиотека использовала Socket.IO в качестве механизма сигнализации, обеспечивающего быструю двунаправленную связь между сервером и клиентами, заботясь о передаче сообщений, необходимых для установления соединения WebRTC.

Чтобы каждый клиент мог отслеживать, к кому он подключен, была использована структура данных, в данном случае объект, ключ которого является уникальным идентификатором (идентификатор сокета удаленного однорангового узла), а значение - созданным экземпляром RTCPeerConnection. Таким образом, эта структура данных может содержать множество экземпляров RTCPeerConnection, каждый из которых идентифицируется идентификатором сокета удаленного узла.

connections = {remotePeerId: RTCPeerConnection, ...};

При отправке сообщения, такого как предложение, удаленному одноранговому узлу, сервер сигнализации добавляет идентификатор сокета (или любой другой уникальный идентификатор) локального однорангового узла до ретрансляции сообщения, чтобы удаленный одноранговый узел мог найти соответствующее RTCPeerConnection из структура данных, чтобы правильно установить удаленное описание, сгенерировать ответ и установить локальное описание. Та же логика применяется к сообщениям, относящимся к кандидатам ICE.

// server
  socket.on('signal', (toId, message) => {
    // relay the message to the recipient including the sender's id
    io.to(toId).emit('signal', socket.id, message);
  });
// client
  connections[remotePeerId] = new RTCPeerConnection();
  socket.on('signal', (fromId, message) => {
    var currentConnection = connections[fromId];
    if(currentConnection) {
      if(message.type === 'answer') {
        currentConnection.receiveAnswer(message.answer);
      } else if (message.type === 'candidate') {
        currentConnection.addCandidate(message.candidate);
      }
    }
  });

Надеюсь, эта статья предоставила некоторые разъяснения о том, как динамически создавать и управлять несколькими соединениями WebRTC для каждого клиента браузера!