Google is committed to advancing racial equity for Black communities. See how.
Ta strona została przetłumaczona przez Cloud Translation API.
Switch to English

Pierwsze kroki z połączeniami równorzędnymi

Połączenia równorzędne to część specyfikacji WebRTC, która dotyczy łączenia dwóch aplikacji na różnych komputerach w celu komunikacji za pomocą protokołu peer-to-peer. Komunikacja między peerami może odbywać się za pomocą wideo, audio lub dowolnych danych binarnych (dla klientów obsługujących interfejs API RTCDataChannel ). Aby odkryć, w jaki sposób mogą się łączyć dwa węzły równorzędne, obaj klienci muszą podać konfigurację serwera ICE. Jest to serwer STUN lub TURN, a ich rolą jest dostarczanie kandydatów ICE każdemu klientowi, który jest następnie przesyłany do zdalnego peera. To przenoszenie kandydatów ICE jest powszechnie nazywane sygnalizacją.

Sygnalizacja

Specyfikacja WebRTC zawiera interfejsy API do komunikacji z serwerem ICE (Internet Connectivity Establishment), ale komponent sygnalizacyjny nie jest częścią tego. Sygnalizacja jest potrzebna, aby dwa peery mogły dzielić się tym, jak powinny się łączyć. Zwykle jest to rozwiązywane za pomocą zwykłego internetowego interfejsu API opartego na protokole HTTP (tj. Usługi REST lub innego mechanizmu RPC), w którym aplikacje internetowe mogą przekazywać niezbędne informacje przed zainicjowaniem połączenia równorzędnego.

Poniższy fragment kodu pokazuje, jak ta fikcyjna usługa sygnalizacyjna może służyć do asynchronicznego wysyłania i odbierania wiadomości. W razie potrzeby zostanie to wykorzystane w pozostałych przykładach w tym przewodniku.

 // Set up an asynchronous communication channel that will be
// used during the peer connection setup
const signalingChannel = new SignalingChannel(remoteClientId);
signalingChannel.addEventListener('message', message => {
    // New message from remote client received
});

// Send an asynchronous message to the remote client
signalingChannel.send('Hello!');
 

Sygnalizacja może być implementowana na wiele różnych sposobów, a specyfikacja WebRTC nie preferuje żadnego konkretnego rozwiązania.

Inicjowanie połączeń równorzędnych

Każde połączenie równorzędne jest obsługiwane przez obiekt RTCPeerConnection . Konstruktor tej klasy przyjmuje jako parametr pojedynczy obiekt RTCConfiguration . Ten obiekt określa sposób konfiguracji połączenia równorzędnego i powinien zawierać informacje o serwerach ICE, które mają być używane.

Po utworzeniu połączenia RTCPeerConnection musimy utworzyć ofertę SDP lub odpowiedź, w zależności od tego, czy jesteśmy RTCPeerConnection czy odbierającym. Po utworzeniu oferty lub odpowiedzi SDP należy ją przesłać do zdalnego peera innym kanałem. Przekazywanie obiektów SDP do zdalnych peerów nazywane jest sygnalizacją i nie jest objęte specyfikacją WebRTC.

Aby zainicjować konfigurację połączenia równorzędnego od strony wywołującej, tworzymy obiekt RTCPeerConnection a następnie wywołujemy createOffer() aby utworzyć obiekt RTCSessionDescription . Ten opis sesji jest ustawiany jako opis lokalny za pomocą metody setLocalDescription() a następnie jest przesyłany naszym kanałem sygnalizacyjnym do strony odbierającej. Skonfigurowaliśmy również nasłuchiwanie naszego kanału sygnalizacyjnego, gdy odpowiedź na nasz oferowany opis sesji jest odbierana od strony odbierającej.

 async function makeCall() {
    const configuration = {'iceServers': [{'urls': 'stun:stun.l.google.com:19302'}]}
    const peerConnection = new RTCPeerConnection(configuration);
    signalingChannel.addEventListener('message', async message => {
        if (message.answer) {
            const remoteDesc = new RTCSessionDescription(message.answer);
            await peerConnection.setRemoteDescription(remoteDesc);
        }
    });
    const offer = await peerConnection.createOffer();
    await peerConnection.setLocalDescription(offer);
    signalingChannel.send({'offer': offer});
}
 

Po stronie odbierającej czekamy na przychodzącą ofertę, zanim utworzymy naszą instancję RTCPeerConnection . Gdy to zrobimy, ustawiamy otrzymaną ofertę za pomocą setRemoteDescription() . Następnie wywołujemy createAnswer() aby stworzyć odpowiedź na otrzymaną ofertę. Ta odpowiedź jest ustawiana jako opis lokalny za pomocą setLocalDescription() a następnie wysyłana do strony wywołującej przez nasz serwer sygnalizacyjny.

 const peerConnection = new RTCPeerConnection(configuration);
signalingChannel.addEventListener('message', async message => {
    if (message.offer) {
        peerConnection.setRemoteDescription(new RTCSessionDescription(message.offer));
        const answer = await peerConnection.createAnswer();
        await peerConnection.setLocalDescription(answer);
        signalingChannel.send({'answer': answer});
    }
});
 

Gdy obaj rówieśnicy ustawią zarówno opis sesji lokalnej, jak i zdalnej, znają możliwości zdalnego partnera. Nie oznacza to, że połączenie między peerami jest gotowe. Aby to zadziałało, musimy zebrać kandydatów ICE z każdego peera i przesłać (przez kanał sygnalizacyjny) do drugiego peera.

Kandydaci do ICE

Zanim dwaj rówieśnicy będą mogli komunikować się za pomocą WebRTC, muszą wymienić informacje o połączeniach. Ponieważ warunki sieciowe mogą się różnić w zależności od wielu czynników, usługa zewnętrzna jest zwykle używana do wykrywania potencjalnych kandydatów do połączenia z równorzędnym. Ta usługa nazywa się ICE i używa serwera STUN lub TURN. STUN to skrót od Session Traversal Utilities dla NAT i jest zwykle używany pośrednio w większości aplikacji WebRTC.

TURN (Traversal Using Relay NAT) to bardziej zaawansowane rozwiązanie, które zawiera protokoły STUN, a większość komercyjnych usług opartych na WebRTC korzysta z serwera TURN do nawiązywania połączeń między urządzeniami równorzędnymi. Interfejs API WebRTC obsługuje bezpośrednio zarówno STUN, jak i TURN, i jest on zebrany pod bardziej kompletnym terminem ustanowienie łączności internetowej. Podczas tworzenia połączenia WebRTC zwykle udostępniamy jeden lub kilka serwerów ICE w konfiguracji dla obiektu RTCPeerConnection .

Trickle ICE

Po RTCPeerConnection obiektu RTCPeerConnection podstawowa struktura korzysta z dostarczonych serwerów ICE do gromadzenia kandydatów do ustanowienia łączności (kandydatów ICE). Zdarzenie icegatheringstatechange na RTCPeerConnection sygnalizuje, w jakim stanie jest gromadzenie ICE ( new , gathering lub complete ).

Podczas gdy peer może poczekać, aż gromadzenie ICE zostanie zakończone, zwykle bardziej efektywne jest użycie techniki „strużki lodu” i przesłanie każdego kandydata ICE do zdalnego peera, gdy zostanie wykryty. To znacznie skróci czas konfiguracji połączenia równorzędnego i umożliwi rozpoczęcie rozmowy wideo z mniejszymi opóźnieniami.

Aby zebrać kandydatów do ICE, wystarczy dodać słuchacza do wydarzenia icecandidate . RTCPeerConnectionIceEvent emitowane przez ten detektor będzie zawierało właściwość candidate która reprezentuje nowego kandydata, który powinien zostać wysłany do zdalnego peera (patrz Sygnalizacja).

 // Listen for local ICE candidates on the local RTCPeerConnection
peerConnection.addEventListener('icecandidate', event => {
    if (event.candidate) {
        signalingChannel.send({'new-ice-candidate': event.candidate});
    }
});

// Listen for remote ICE candidates and add them to the local RTCPeerConnection
signalingChannel.addEventListener('message', async message => {
    if (message.iceCandidate) {
        try {
            await peerConnection.addIceCandidate(message.iceCandidate);
        } catch (e) {
            console.error('Error adding received ice candidate', e);
        }
    }
});
 

Nawiązano połączenie

Po otrzymaniu kandydatów ICE powinniśmy oczekiwać, że stan naszego połączenia równorzędnego ostatecznie zmieni się na stan połączony. Aby to wykryć, dodajemy odbiornik do naszego RTCPeerConnection gdzie nasłuchujemy zdarzeń zmiany stanu connectionstatechange .

 // Listen for connectionstatechange on the local RTCPeerConnection
peerConnection.addEventListener('connectionstatechange', event => {
    if (peerConnection.connectionState === 'connected') {
        // Peers connected!
    }
});
 

Dokumentacja interfejsu API RTCPeerConnection