Erste Schritte mit Peer-Verbindungen

Peer-Verbindungen sind der Teil der WebRTC-Spezifikationen, der sich mit zwei Anwendungen auf verschiedenen Computern zur Kommunikation über ein Peer-to-Peer-Protokoll. Die Kommunikation zwischen Peers kann Video-, Audio- oder Beliebige Binärdaten (für Clients, die die RTCDataChannel API unterstützen). In um herauszufinden, wie zwei Mitbewerber sich vernetzen können, müssen beide Kunden ein ICE Serverkonfiguration. Dies ist entweder ein STUN oder ein Turn-Server und ihre Rolle ist jedem Kunden ICE-Kandidaten zur Verfügung zu stellen, die dann an das Remote-Team Peer. Die Übertragung von ICE-Kandidaten wird allgemein als Signalisierung bezeichnet.

Signalisierung

Die WebRTC-Spezifikation enthält APIs für die Kommunikation mit einem ICE Verbindung einrichten) Server, aber die Signalisierungskomponente ist nicht Teil von . Signaling ist erforderlich, damit zwei Mitlernende sich darüber austauschen können, wie sie sich verbinden sollen. In der Regel wird dies durch eine reguläre HTTP-basierte Web-API (d. h. eine REST) gelöst. oder einem anderen RPC-Verfahren), über den Webanwendungen die erforderlichen bevor die Peer-Verbindung hergestellt wird.

Das folgende Code-Snippet zeigt, wie mit diesem fiktiven Signalisierungsdienst Nachrichten asynchron senden und empfangen können. Diese wird in den verbleibenden Beispiele in diesem Leitfaden.

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

Signalisierung kann auf viele verschiedene Arten implementiert werden. Spezifikation keine bestimmte Lösung bevorzugt.

Peer-Verbindungen initiieren

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

Sobald die RTCPeerConnection erstellt ist, müssen wir ein SDP-Angebot erstellen oder antworten, je nachdem, ob wir der anrufende Peer oder der empfangende Peer sind. Sobald der SDP oder eine Antwort erstellt wird, muss sie über eine über einen anderen Kanal. Die Übergabe von SDP-Objekten an Remote-Peers nicht durch die WebRTC-Spezifikation abgedeckt ist.

Um die Einrichtung der Peer-Verbindung auf der aufrufenden Seite zu initiieren, erstellen wir einen RTCPeerConnection-Objekt und rufen Sie dann createOffer() auf, um ein RTCSessionDescription-Objekt. Diese Sitzungsbeschreibung ist als lokale mit setLocalDescription() und wird dann über unsere Signalisierung auf die Empfängerseite übertragen. Außerdem richten wir einen Listener für unsere wenn eine Antwort auf die von uns angebotene Sitzungsbeschreibung der Empfängerseite.

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 Empfängerseite warten wir auf ein eingehendes Angebot, bevor wir unsere RTCPeerConnection-Instanz. Anschließend legen wir das erhaltene Angebot setRemoteDescription() Als Nächstes rufen wir createAnswer() auf, um eine Antwort auf erhalten haben. Diese Antwort wird als lokale Beschreibung mit setLocalDescription() und dann über unsere Signalisierung an die anrufende Seite gesendet Server.

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 die Beschreibungen der lokalen und der Remote-Sitzung festgelegt haben, Funktionen des Remote-Peers kennen. Das bedeutet nicht, dass die Verbindung zwischen den Peers bereit. Damit das funktioniert, müssen wir das ICE-Konto Kandidaten bei jedem Peer und Übertragung (über den Signalisierungskanal) an die andere Peer.

ICE-Kandidaten

Bevor zwei Peers über WebRTC kommunizieren können, müssen sie sich austauschen. Verbindungsinformationen. Da die Netzwerkbedingungen je nach wird in der Regel ein externer Dienst verwendet, mögliche Kandidaten für die Verbindung mit einem Kollegen. Dieser Service heißt ICE und ist mit einem STUN- oder TURN-Server. STUN steht für Session Traversal (Sitzungsdurchlauf). Dienstprogramme für NAT und wird in der Regel indirekt in den meisten WebRTC-Anwendungen verwendet.

TURN (Traversal Using Relay NAT) ist die fortschrittlichere Lösung, die Folgendes beinhaltet: Für die STUN-Protokolle und die meisten kommerziellen WebRTC-basierten Dienste wird ein TURN-Server verwendet. zum Herstellen von Verbindungen zwischen Peers. Die WebRTC API unterstützt sowohl STUN die sich unter dem umfassenderen Begriff Internet finden, Verbindungsherstellung. Beim Erstellen einer WebRTC-Verbindung einen oder mehrere ICE-Server in der Konfiguration für die RTCPeerConnection-Objekt.

Trickle-ICE

Sobald ein RTCPeerConnection-Objekt erstellt wurde, verwendet das zugrunde liegende Framework das stellten ICE-Server bereit, um Kandidaten für den Verbindungsaufbau (ICE) Kandidaten). Das Ereignis „icegatheringstatechange“ am RTCPeerConnection Signal in welchem Status sich die ICE-Versammlung befindet (new, gathering oder complete).

Es ist zwar möglich, dass ein Peer abwartet, bis die ICE-Erfassung abgeschlossen ist, ist normalerweise viel effizienter, ein „Reißeis“ zu verwenden. Technik und Übertragung jedem ICE-Kandidaten an das Remote-Peer, wenn er erkannt wird. Dadurch wird die Einrichtungszeit für die Peer-Verbindung erheblich reduzieren und rufen Sie uns an, um mit weniger Verzögerungen loslegen zu können.

Fügen Sie dem icecandidate-Ereignis einfach einen Listener hinzu, um ICE-Kandidaten zu erfassen. Die für diesen Listener ausgegebene RTCPeerConnectionIceEvent enthält candidate-Eigenschaft, die einen neuen Kandidaten darstellt, der an die Remote-Peer (siehe "Signale").

// 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 die ICE-Kandidaten eingegangen sind, sollten wir mit dem Status des anderen Partners rechnen. die Verbindung in den Status „Verbunden“ wechselt. Um dies zu erkennen, fügen wir Hörer unserer RTCPeerConnection, wobei wir auf connectionstatechange warten Ereignisse.

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

RTCPeerConnection-API Dokumentation