Firebase + WebRTC-Codelab

1. Einführung

In diesem Codelab erfahren Sie, wie Sie mit der WebRTC API in Ihrem Browser und Cloud Firestore für die Signalisierung eine einfache Videokonferenzanwendung erstellen. Die Anwendung heißt FirebaseRTC und dient als einfaches Beispiel, das Ihnen die Grundlagen der Erstellung von WebRTC-fähigen Anwendungen vermittelt.

Lerninhalte

  • Videoanrufe in einer Webanwendung mit WebRTC starten
  • Signale für die Remote-Party mit Cloud Firestore

Voraussetzungen

Bevor du dieses Codelab startest, solltest du prüfen, ob du Folgendes installiert hast:

  • npm, die normalerweise in Node.js enthalten ist, wird Node LTS empfohlen

2. Firebase-Projekt erstellen und einrichten

Firebase-Projekt erstellen

  1. Klicken Sie in der Firebase Console auf "Projekt hinzufügen" und benennen Sie das Firebase-Projekt "FirebaseRTC".

Merken Sie sich die Projekt-ID für Ihr Firebase-Projekt.

  1. Klicken Sie auf CreateProjekt erstellen“.

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

  • Cloud Firestore, um strukturierte Daten in der Cloud zu speichern und sofort eine Benachrichtigung zu erhalten, wenn die Daten aktualisiert werden
  • Firebase Hosting zum Hosten und Bereitstellen Ihrer statischen Inhalte

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

Cloud Firestore aktivieren

Die Anwendung verwendet Cloud Firestore, um die Chatnachrichten zu speichern und neue Chatnachrichten zu empfangen.

Sie müssen Cloud Firestore aktivieren:

  1. Klicken Sie im Menü DevelopEntwicklung“ der Firebase Console auf DatabaseDatenbank“.
  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.

Mit dem Testmodus können Sie während der Entwicklung frei in die Datenbank schreiben. Wir werden unsere Datenbank später in diesem Codelab sicherer machen.

3. Beispielcode abrufen

Klonen Sie das GitHub-Repository von der Befehlszeile aus:

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

Der Beispielcode wurde im Verzeichnis FirebaseRTC geklont. Prüfen Sie, ob die Befehlszeile ab jetzt auf diesem Verzeichnis ausgeführt wird:

cd FirebaseRTC

Starter-App importieren

Öffnen Sie die Dateien in FirebaseRTC in Ihrem Editor und ändern Sie sie wie unten beschrieben. Dieses Verzeichnis enthält den Startcode für das Codelab, das aus einer noch nicht funktionsfähigen WebRTC-App besteht. Wir werden es in diesem Codelab funktionsfähig machen.

4. Firebase-Befehlszeile installieren

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

  1. Installieren Sie die Befehlszeile mit dem folgenden npm-Befehl: sh npm -g install firebase-tools
  1. Prüfen Sie mit dem folgenden Befehl, ob die Befehlszeile korrekt installiert wurde: sh firebase --version

Achten Sie darauf, dass die Version der Firebase-Befehlszeile Version 6.7.1 oder höher ist.

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

Sie haben die Webanwendungsvorlage so eingerichtet, dass sie die Konfiguration Ihrer Anwendung für Firebase Hosting aus dem lokalen Verzeichnis und den Dateien Ihrer Anwendung abruft. Dazu müssen Sie Ihre App mit Ihrem Firebase-Projekt verknüpfen.

  1. Verknüpfen Sie die Anwendung mit dem Firebase-Projekt. Führen Sie dazu den folgenden Befehl aus: sh firebase use --add

  2. Wenn Sie dazu aufgefordert werden, wählen Sie Ihre Projekt-ID aus und geben Sie Ihrem Firebase-Projekt einen Alias.

Ein Alias ist nützlich, wenn Sie mehrere Umgebungen haben (Produktion, Staging usw.). Für dieses Codelab verwenden wir jedoch einfach den Alias default.

  1. Folgen Sie den restlichen Anleitungen in der Befehlszeile.

5 Lokalen Server ausführen

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

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

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

Wir verwenden den Firebase Hosting-Emulator, um die 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 Ihre Kopie von FirebaseRTC sehen, die mit Ihrem Firebase-Projekt verbunden wurde.

Die App wurde automatisch mit Ihrem Firebase-Projekt verbunden.

6. Neuen Raum erstellen

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

Jeder Raum enthält das 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 zu implementieren, um mit dem ersten Angebot des Aufrufers einen neuen Raum zu erstellen. Ö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 Aufrufers darstellt. Dies wird als lokale Beschreibung festgelegt und schließlich in das neue Zimmerobjekt in Cloud Firestore geschrieben.

Als Nächstes warten wir auf Änderungen an der Datenbank und erkennen, ob eine Antwort vom Empfänger hinzugefügt wurde.

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. Dies wird als Remote-Beschreibung des Aufrufers RTCPeerConnection festgelegt.

7. Chatrooms beitreten

Im nächsten Schritt implementieren Sie die Logik für den Beitritt zu einem vorhandenen Raum. Der Nutzer klickt dazu auf die Schaltfläche Chatroom beitreten und gibt die ID des Chatrooms ein, dem er beitreten möchte. Ihre Aufgabe besteht darin, RTCSessionDescription für die Antwort zu erstellen und den Raum entsprechend in der Datenbank 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 Code oben extrahieren wir das Angebot vom Aufrufer und erstellen eine RTCSessionDescription, die wir als Remote-Beschreibung festgelegt haben. 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 der Aufruferseite aus, wodurch die Remote-Beschreibung basierend auf der Antwort des Aufrufers festgelegt wird. Damit ist der Austausch der RTCSessionDescription-Objekte zwischen dem Aufrufer und dem Aufrufer abgeschlossen.

8. ICE-Kandidaten sammeln

Bevor sich der Aufrufer und der Anrufer miteinander verbinden können, müssen auch ICE-Kandidaten ausgetauscht werden, die WebRTC mitteilen, wie sie eine Verbindung zum Remote-Peer herstellen können. Als Nächstes implementieren Sie den Code, der ICE-Kandidaten überwacht, und fügt sie einer Sammlung in der Datenbank hinzu. 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());
                peerConneciton.addIceCandidate(candidate);
            }
        });
    })
}

Diese Funktion hat zwei Aufgaben. Sie erfasst ICE-Kandidaten von der WebRTC API, fügt sie der Datenbank hinzu, überwacht hinzugefügte ICE-Kandidaten vom Remote-Peer und fügt sie der Instanz RTCPeerConnection hinzu. Wenn Sie Datenbankänderungen überwachen, ist es wichtig, alle Elemente herauszufiltern, die keine neue Ergänzung sind, da wir sonst immer wieder die gleichen ICE-Kandidaten hinzugefügt hätten.

9. Fazit

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

Weitere Informationen finden Sie in den folgenden Ressourcen:

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