Пиринговые соединения

RTCPeerConnection — это центральный интерфейс API WebRTC. Он представляет собой соединение между локальным и удалённым узлами и предоставляет все функции и события, необходимые для установления соединения.

Установление однорангового соединения

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

  1. Создайте новый экземпляр RTCPeerConnection с соответствующей конфигурацией ICE.
  2. Создайте локальное описание SDP с помощью RTCPeerConnection.createOffer() .
  3. Установите локальное описание SDP с помощью RTCPeerConnection.setLocalDescription() .
  4. Передать (используя сигнальную службу) локальное описание SDP удаленному узлу.
  5. Зарегистрируйте прослушиватель событий icecandidate на RTCPeerConnection .
  6. Для каждого события icecandidate передайте его (используя сигнальную службу) удаленному узлу.
  7. Дождитесь входящего удаленного описания SDP от службы сигнализации и установите его с помощью RTCPeerConnection.setRemoteDescription() .
  8. Ожидайте входящие удаленные ICE-кандидаты от службы сигнализации и добавляйте их с помощью RTCPeerConnection.addIceCandidate()

Со стороны вызываемого абонента процесс немного отличается.

  1. Создайте новый экземпляр RTCPeerConnection с соответствующей конфигурацией ICE.
  2. Дождитесь входящего удаленного описания SDP от службы сигнализации и установите его с помощью RTCPeerConnection.setRemoteDescription() .
  3. Создайте ответ для удаленного описания SDP, вызвав RTCPeerConnection.createAnswer() .
  4. Передать (с помощью сигнальной службы) ответ удаленному узлу.
  5. Зарегистрируйте прослушиватель событий icecandidate на RTCPeerConnection .
  6. Для каждого события icecandidate передайте его (используя сигнальную службу) удаленному узлу.
  7. Ожидайте входящие удаленные ICE-кандидаты от службы сигнализации и добавляйте их с помощью RTCPeerConnection.addIceCandidate()

Проблема этого API заключается в том, что большинство операций выполняются асинхронно, что часто усложняет реализацию WebRTC-приложения. Многие функции возвращают Promise , который необходимо разрешить перед продолжением следующего этапа процесса.

При реализации приложения с использованием этого API разработчику рекомендуется использовать async и await вместо регистрации слушателей (с помощью Promise.then() ), так как это упрощает понимание кода. Рассмотрим следующий пример:

function createAndSendOffer(peerConnection, signallingService) {
    peerConnection.createOffer()
                  .then(offer => {
                      signallingService.send({
                          type: 'offer',
                          data: offer
                      });
                  });
}

При написании кода выше с использованием async и await мы получаем следующее:

async function createAndSendOffer(peerConnection, signallingService) {
    const offer = await peerConnection.createOffer();
    signallingService.send({
        type: 'offer',
        data: offer
    });
}