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

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

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

Приложения, реализующие функциональность 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
    });
}