Połączenia równorzędne

RTCPeerConnection to centralny interfejs w API WebRTC. Reprezentuje połączenie między lokalnym i zdalnym węzłem oraz udostępnia wszystkie funkcje i zdarzenia niezbędne do nawiązania połączenia.

Nawiązywanie połączenia równorzędnego

Aplikacje korzystające z funkcji WebRTC zwykle w dużym stopniu bazują na interfejsie RTCPeerConnection. Po stronie dzwoniącego (czyli osoby inicjującej połączenie) proces nawiązywania połączenia wygląda zwykle tak:

  1. Utwórz nową instancję RTCPeerConnection z odpowiednią konfiguracją ICE.
  2. Utwórz lokalny opis SDP za pomocą RTCPeerConnection.createOffer().
  3. Ustaw lokalny opis SDP za pomocą polecenia RTCPeerConnection.setLocalDescription().
  4. Przesyłanie (za pomocą usługi sygnalizacyjnej) lokalnego opisu SDP do zdalnego urządzenia.
  5. Zarejestruj detektor zdarzeń icecandidate na obiekcie RTCPeerConnection.
  6. W przypadku każdego zdarzenia icecandidate przenieś je (za pomocą usługi sygnalizacyjnej) do zdalnego elementu równorzędnego.
  7. Poczekaj na przychodzący zdalny opis SDP z usługi sygnalizacyjnej i ustaw go za pomocą RTCPeerConnection.setRemoteDescription().
  8. Poczekaj na przychodzące zdalne kandydaty ICE z usługi sygnalizacyjnej i dodaj je za pomocą RTCPeerConnection.addIceCandidate().

Po stronie osoby odbierającej połączenie proces wygląda nieco inaczej.

  1. Utwórz nową instancję RTCPeerConnection z odpowiednią konfiguracją ICE.
  2. Poczekaj na przychodzący zdalny opis SDP z usługi sygnalizacyjnej i ustaw go za pomocą RTCPeerConnection.setRemoteDescription().
  3. Utwórz odpowiedź na opis SDP zdalnego urządzenia, wywołując funkcję RTCPeerConnection.createAnswer().
  4. Przekaż (za pomocą usługi sygnalizacyjnej) odpowiedź do zdalnego urządzenia.
  5. Zarejestruj detektor zdarzeń icecandidate na obiekcie RTCPeerConnection.
  6. W przypadku każdego zdarzenia icecandidate przenieś je (za pomocą usługi sygnalizacyjnej) do zdalnego elementu równorzędnego.
  7. Poczekaj na przychodzące zdalne kandydaty ICE z usługi sygnalizacyjnej i dodaj je za pomocą RTCPeerConnection.addIceCandidate().

Problem z tym interfejsem API polega na tym, że większość tych operacji jest asynchroniczna, co często komplikuje rzeczywistą implementację aplikacji WebRTC. Wiele funkcji zwraca wartość Promise, którą należy rozwiązać, zanim będzie można przejść do następnego kroku procesu.

Podczas wdrażania aplikacji za pomocą tego interfejsu API zalecamy używanie funkcji asyncawait zamiast rejestrowania odbiorników (za pomocą funkcji Promise.then()), ponieważ dzięki temu kod jest łatwiejszy do śledzenia. Rozważ ten przykład:

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

Jeśli powyższy kod napiszemy za pomocą znaków asyncawait, otrzymamy:

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