Google is committed to advancing racial equity for Black communities. See how.
Diese Seite wurde von der Cloud Translation API übersetzt.
Switch to English

Erste Schritte mit Peer-Verbindungen

Peer-Verbindungen sind Teil der WebRTC-Spezifikationen, die sich mit der Verbindung zweier Anwendungen auf verschiedenen Computern zur Kommunikation über ein Peer-to-Peer-Protokoll befassen. Die Kommunikation zwischen Peers kann aus Video-, Audio- oder beliebigen Binärdaten bestehen (für Clients, die die RTCDataChannel API unterstützen). Um herauszufinden, wie zwei Peers eine Verbindung herstellen können, müssen beide Clients eine ICE-Serverkonfiguration bereitstellen. Dies ist entweder ein STUN- oder ein TURN-Server. Ihre Aufgabe besteht darin, jedem Client ICE-Kandidaten bereitzustellen, die dann an den Remote-Peer übertragen werden. Diese Übertragung von ICE-Kandidaten wird üblicherweise als Signalisierung bezeichnet.

Signalisierung

Die WebRTC-Spezifikation enthält APIs für die Kommunikation mit einem ICE-Server (Internet Connectivity Establishment), die Signalisierungskomponente ist jedoch nicht Teil davon. Die Signalisierung ist erforderlich, damit zwei Peers gemeinsam nutzen können, wie sie sich verbinden sollen. Normalerweise wird dies durch eine reguläre HTTP-basierte Web-API (dh einen REST-Service oder einen anderen RPC-Mechanismus) gelöst, bei der Webanwendungen die erforderlichen Informationen weiterleiten können, bevor die Peer-Verbindung hergestellt wird.

Das folgende Code-Snippet zeigt, wie dieser fiktive Signalisierungsdienst zum asynchronen Senden und Empfangen von Nachrichten verwendet werden kann. Dies wird bei Bedarf in den übrigen Beispielen in diesem Handbuch verwendet.

 // 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!');
 

Die Signalisierung kann auf viele verschiedene Arten implementiert werden, und die WebRTC-Spezifikation bevorzugt keine spezifische Lösung.

Peer-Verbindungen initiieren

Jede Peer-Verbindung wird von einem RTCPeerConnection Objekt verwaltet. Der Konstruktor für diese Klasse verwendet ein einzelnes RTCConfiguration Objekt als Parameter. Dieses Objekt definiert, wie die Peer-Verbindung eingerichtet wird, und sollte Informationen zu den zu verwendenden ICE-Servern enthalten.

Sobald die RTCPeerConnection erstellt wurde, müssen wir ein SDP-Angebot oder eine Antwort erstellen, je nachdem, ob wir der anrufende oder der empfangende Peer sind. Sobald das SDP-Angebot oder die SDP-Antwort erstellt wurde, muss sie über einen anderen Kanal an den Remote-Peer gesendet werden. Das Übergeben von SDP-Objekten an Remote-Peers wird als Signalisierung bezeichnet und ist in der WebRTC-Spezifikation nicht enthalten.

Um den Peer-Verbindungsaufbau von der aufrufenden Seite aus zu initiieren, erstellen wir ein RTCPeerConnection Objekt und rufen dann createOffer() auf, um ein RTCSessionDescription Objekt zu erstellen. Diese Sitzungsbeschreibung wird mit setLocalDescription() als lokale Beschreibung setLocalDescription() und dann über unseren Signalisierungskanal an die empfangende Seite gesendet. Wir haben auch einen Listener für unseren Signalisierungskanal eingerichtet, wenn eine Antwort auf unsere angebotene Sitzungsbeschreibung von der empfangenden Seite empfangen wird.

 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});
}
 

Auf der Empfangsseite warten wir auf ein eingehendes Angebot, bevor wir unsere RTCPeerConnection Instanz erstellen. Sobald dies erledigt ist, legen wir das erhaltene Angebot mit setRemoteDescription() . Als nächstes rufen wir createAnswer() auf, um eine Antwort auf das erhaltene Angebot zu erstellen. Diese Antwort wird mit setLocalDescription() als lokale Beschreibung setLocalDescription() und dann über unseren Signalisierungsserver an die aufrufende Seite gesendet.

 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});
    }
});
 

Sobald die beiden Peers sowohl die lokale als auch die Remote-Sitzungsbeschreibung festgelegt haben, kennen sie die Funktionen des Remote-Peers. Dies bedeutet nicht, dass die Verbindung zwischen den Peers bereit ist. Damit dies funktioniert, müssen wir die ICE-Kandidaten bei jedem Peer sammeln und (über den Signalisierungskanal) zum anderen Peer übertragen.

ICE-Kandidaten

Bevor zwei Peers über WebRTC kommunizieren können, müssen sie Konnektivitätsinformationen austauschen. Da die Netzwerkbedingungen in Abhängigkeit von einer Reihe von Faktoren variieren können, wird normalerweise ein externer Dienst verwendet, um die möglichen Kandidaten für die Verbindung mit einem Peer zu ermitteln. Dieser Dienst heißt ICE und verwendet entweder einen STUN- oder einen TURN-Server. STUN steht für Session Traversal Utilities für NAT und wird normalerweise indirekt in den meisten WebRTC-Anwendungen verwendet.

TURN (Traversal Using Relay NAT) ist die fortschrittlichere Lösung, die die STUN-Protokolle enthält. Die meisten kommerziellen WebRTC-basierten Dienste verwenden einen TURN-Server zum Herstellen von Verbindungen zwischen Peers. Die WebRTC-API unterstützt sowohl STUN als auch TURN direkt und wird unter dem vollständigeren Begriff Internet Connectivity Establishment zusammengefasst. Beim Erstellen einer WebRTC-Verbindung stellen wir normalerweise einen oder mehrere ICE-Server in der Konfiguration für das RTCPeerConnection Objekt RTCPeerConnection .

Riesel-EIS

Sobald ein RTCPeerConnection Objekt erstellt wurde, verwendet das zugrunde liegende Framework die bereitgestellten ICE-Server, um Kandidaten für den Verbindungsaufbau (ICE-Kandidaten) zu sammeln. Das Ereignis icegatheringstatechange auf RTCPeerConnection signalisiert, in welchem ​​Status sich die ICE-Erfassung befindet ( new , gathering oder complete ).

Während ein Peer warten kann, bis die ICE-Erfassung abgeschlossen ist, ist es normalerweise viel effizienter, eine "Trickle Ice" -Technik zu verwenden und jeden ICE-Kandidaten an den Remote-Peer zu übertragen, sobald er entdeckt wird. Dadurch wird die Einrichtungszeit für die Peer-Konnektivität erheblich verkürzt und ein Videoanruf kann mit weniger Verzögerungen gestartet werden.

Um ICE-Kandidaten zu sammeln, fügen Sie einfach einen Listener für das icecandidate Event hinzu. Das auf diesem Listener RTCPeerConnectionIceEvent enthält eine candidate , die einen neuen Kandidaten darstellt, der an den Remote-Peer gesendet werden soll (siehe Signalisierung).

 // 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);
        }
    }
});
 

Verbindung hergestellt

Sobald ICE-Kandidaten empfangen wurden, sollten wir erwarten, dass sich der Status für unsere Peer-Verbindung schließlich in einen verbundenen Status ändert. Um dies zu erkennen, fügen wir unserer RTCPeerConnection einen Listener RTCPeerConnection in dem wir auf Ereignisse zum RTCPeerConnection des connectionstatechange RTCPeerConnection .

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

Dokumentation zur RTCPeerConnection-API