Firebase + WebRTC-Codelab

1. Einführung

In diesem Codelab erfahren Sie, wie Sie mit der WebRTC API in Ihrem Browser und in Cloud Firestore eine einfache Videochat-Anwendung für die Signalerstellung erstellen. Die App heißt FirebaseRTC und dient als einfaches Beispiel, in dem die Grundlagen des Erstellens von WebRTC-fähigen Anwendungen vermittelt werden.

Lerninhalte

  • Videoanrufe in einer Webanwendung mit WebRTC starten
  • Signaling an die Remote-Party mit Cloud Firestore

Voraussetzungen

Bevor du mit diesem Codelab beginnst, solltest du Folgendes tun:

  • npm, die normalerweise mit Node.js enthalten ist – LTS-Knoten wird empfohlen

2. Firebase-Projekt erstellen und einrichten

Firebase-Projekt erstellen

  1. Klicken Sie in der Firebase Console auf „Projekt hinzufügen“. Geben Sie dann einen Namen für das Firebase-Projekt FirebaseRTC ein.

Projekt-ID für das Firebase-Projekt beibehalten.

  1. Klicken Sie auf „Projekt erstellen“.

Die Anwendung, die Sie erstellen möchten, verwendet zwei Firebase-Dienste, die im Web verfügbar sind:

  • Cloud Firestore zum Speichern strukturierter Daten in der Cloud und Sofortbenachrichtigung, wenn die Daten aktualisiert werden
  • Firebase Hosting zum Hosten und Bereitstellen statischer Assets

Für dieses spezifische Codelab haben Sie Firebase Hosting bereits in dem Projekt konfiguriert, das Sie klonen. Für Cloud Firestore werden Sie jedoch durch die Konfiguration und Aktivierung der Dienste in der Firebase Console geführt.

Cloud Firestore aktivieren

Die Anwendung speichert mit Cloud Firestore die Chatnachrichten und empfängt neue Chatnachrichten.

Sie müssen Cloud Firestore aktivieren:

  1. Klicken Sie im Firebase Console-Menü auf „Datenbank“.
  2. Klicken Sie im Cloud Firestore-Bereich auf Datenbank erstellen.
  3. Wählen Sie die Option Im Testmodus starten aus und klicken Sie auf „Aktivieren“, nachdem Sie den Haftungsausschluss zu den Sicherheitsregeln gelesen haben.

Der Testmodus stellt sicher, dass Sie während der Entwicklung frei in die Datenbank schreiben können. Wir verbessern unsere Datenbank später in diesem Codelab.

3. Beispielcode abrufen

Klonen Sie das GitHub-Repository über die Befehlszeile:

git clone https://github.com/webrtc/FirebaseRTC

Der Beispielcode sollte in das Verzeichnis FirebaseRTC geklont werden. Prüfen Sie, ob die Befehlszeile von jetzt an in diesem Verzeichnis ausgeführt wird:

cd FirebaseRTC

Starter-App importieren

Öffne die Dateien in FirebaseRTC im Editor und ändere sie wie unten beschrieben. Dieses Verzeichnis enthält den Startcode für das Codelab, das aus einer noch nicht funktionsfähigen WebRTC-Anwendung besteht.

4. Firebase-Befehlszeile installieren

Mit der Firebase-Befehlszeile können Sie Ihre Webanwendung lokal bereitstellen und Ihre Webanwendung in Firebase Hosting bereitstellen.

  1. Installieren Sie die Befehlszeile mit dem folgenden npm-Befehl: sh npm -g install firebase-tools
  1. Prüfe, ob die Befehlszeile korrekt installiert wurde. Führe dazu den folgenden Befehl aus: sh firebase --version

Die Version der Firebase CLI muss Version 6.7.1 oder höher sein.

  1. Autorisieren Sie die Firebase CLI mit dem folgenden Befehl: sh firebase login

Sie haben die Web-App-Vorlage eingerichtet, um Ihre App-Konfiguration für Firebase Hosting aus dem lokalen Verzeichnis und den Dateien Ihrer App abzurufen. Dazu müssen Sie Ihre App jedoch mit Ihrem Firebase-Projekt verknüpfen.

  1. Verbinden Sie die App mit dem Firebase-Projekt, indem Sie den folgenden Befehl ausführen:sh firebase use --add

  2. Wähle die Projekt-ID aus, wenn du dazu aufgefordert wirst, und gib deinem Firebase-Projekt einen Alias.

Ein Alias ist nützlich, wenn Sie mehrere Umgebungen haben (Produktion, Staging usw.). In diesem Codelab nutzen wir einfach den Alias von default.

  1. Folgen Sie der restlichen Anleitung in der Befehlszeile.

5. Lokalen Server ausführen

Sie können jetzt mit der Arbeit an unserer App beginnen. Lassen Sie die Anwendung lokal ausführen.

  1. Führen Sie den folgenden Firebase CLI-Befehl aus: sh firebase serve --only hosting

  2. Die Befehlszeile sollte folgende Antwort enthalten: hosting: Local server: http://localhost:5000

Wir verwenden den Firebase Hosting Emulator, um unsere App lokal bereitzustellen. Die Webanwendung sollte jetzt unter http://localhost:5000 verfügbar sein.

  1. Öffnen Sie die Anwendung unter http://localhost:5000.

Sie sollten eine Kopie von FirebaseRTC sehen, die mit Ihrem Firebase-Projekt verbunden ist.

Die App wurde automatisch mit Ihrem Firebase-Projekt verbunden.

6. Neuer Chatroom wird erstellt

In dieser Anwendung wird jede Videochatsitzung als Chatroom bezeichnet. Nutzer können durch Klicken auf eine Schaltfläche in ihrer Anwendung einen neuen Chatroom erstellen. Dadurch wird eine ID generiert, mit der der Remote-Teilnehmer demselben Raum beitreten kann. Die ID wird in Cloud Firestore für jeden Raum als Schlüssel verwendet.

Jedes Zimmer enthält die RTCSessionDescriptions für das Angebot und die Antwort sowie zwei separate Sammlungen mit ICE-Kandidaten von jeder Partei.

Ihre erste Aufgabe besteht darin, den fehlenden Code zum Erstellen eines neuen Zimmers mit dem anfänglichen Angebot des Anrufers zu implementieren. Öffnen Sie public/app.js, suchen Sie den Kommentar „// Add code for creating a room here“ und fügen Sie den folgenden Code hinzu:

const offer = await peerConnection.createOffer();
await peerConnection.setLocalDescription(offer);

const roomWithOffer = {
    offer: {
        type: offer.type,
        sdp: offer.sdp
    }
}
const roomRef = await db.collection('rooms').add(roomWithOffer);
const roomId = roomRef.id;
document.querySelector('#currentRoom').innerText = `Current room is ${roomId} - You are the caller!`

Die erste Zeile erstellt eine RTCSessionDescription, die das Angebot des Anrufers darstellt. Diese wird dann als lokale Beschreibung festgelegt und schließlich in das neue Zimmerobjekt in Cloud Firestore geschrieben.

Als Nächstes warten wir auf Änderungen in der Datenbank, um zu erkennen, ob der Aufrufer eine Antwort hinzugefügt hat.

roomRef.onSnapshot(async snapshot -> {
    console.log('Got updated room:', snapshot.data());
    const data = snapshot.data();
    if (!peerConnection.currentRemoteDescription && data.answer) {
        console.log('Set remote description: ', data.answer);
        const answer = new RTCSessionDescription(data.answer)
        await peerConnection.setRemoteDescription(answer);
    }
});

Dadurch wird gewartet, bis der Aufrufer RTCSessionDescription für die Antwort schreibt und dieses als Remotebeschreibung für den Aufrufer RTCPeerConnection festlegt.

7. Einem Chatroom beitreten

Im nächsten Schritt implementieren Sie die Logik für den Beitritt zu einem vorhandenen Chatroom. Der Nutzer klickt dazu auf die Schaltfläche Mitglied werden und gibt die ID des Chatrooms ein, an dem er teilnehmen möchte. Ihre Aufgabe besteht darin, die RTCSessionDescription für die Antwort zu implementieren und den Raum in der Datenbank entsprechend zu aktualisieren.

const offer = roomSnapshot.data().offer;
await peerConnection.setRemoteDescription(offer);
const answer = await peerConnection.createAnswer();
await peerConnection.setLocalDescription(answer);

const roomWithAnswer = {
    answer: {
        type: answer.type,
        sdp: answer.sdp
    }
}
await roomRef.update(roomWithAnswer);

Im obigen Code extrahieren wir zuerst das Angebot aus dem Aufrufer und erstellen eine RTCSessionDescription, die wir als Remote-Beschreibung festlegen. Als Nächstes erstellen wir die Antwort, legen sie als lokale Beschreibung fest und aktualisieren die Datenbank. Die Aktualisierung der Datenbank löst den Callback onSnapshot auf Anruferseite aus. Dadurch wird die Remotebeschreibung auf Grundlage der Antwort des Empfängers festgelegt. Dadurch wird der Austausch der RTCSessionDescription-Objekte zwischen dem Aufrufer und dem Aufrufer abgeschlossen.

8. ICE-Kandidaten erfassen

Bevor der Anrufer und der eingeladene Teilnehmer eine Verbindung herstellen können, müssen er auch ICE-Kandidaten austauschen, die WebRTC mitteilen, wie eine Verbindung zum Remote-Peer hergestellt werden kann. Ihre nächste Aufgabe besteht darin, den Code zu implementieren, der ICE-Kandidaten überwacht und dieser Sammlung in der Datenbank hinzufügt. Suchen Sie die Funktion collectIceCandidates und fügen Sie den folgenden Code hinzu:

async function collectIceCandidates(roomRef, peerConnection,
                                    localName, remoteName) {
    const candidatesCollection = roomRef.collection(localName);

    peerConnection.addEventListener('icecandidate', event -> {
        if (event.candidate) {
            const json = event.candidate.toJSON();
            candidatesCollection.add(json);
        }
    });

    roomRef.collection(remoteName).onSnapshot(snapshot -> {
        snapshot.docChanges().forEach(change -> {
            if (change.type === "added") {
                const candidate = new RTCIceCandidate(change.doc.data());
                peerConnection.addIceCandidate(candidate);
            }
        });
    })
}

Diese Funktion bietet zwei Funktionen: Sie erfasst ICE-Kandidaten aus der WebRTC API und fügt sie der Datenbank hinzu. Außerdem werden die ICE-Kandidaten vom Remote-Peer hinzugefügt und ihrer RTCPeerConnection-Instanz hinzugefügt. Es ist wichtig, auf Datenbankänderungen zu achten, um nicht gefilterte Elemente herauszufiltern, da wir sonst immer wieder dieselben ICE-Kandidaten hinzugefügt hätten.

9. Fazit

In diesem Codelab haben Sie erfahren, wie Sie Signalisierung für WebRTC mit Cloud Fit implementieren und wie Sie damit eine einfache Anwendung für Videochats erstellen.

Weitere Informationen finden Sie in den folgenden Ressourcen:

  1. FirebaseRTC-Quellcode
  2. WebRTC-Beispiele
  3. Cloud Firestore