1. Wstęp
Z tego ćwiczenia dowiesz się, jak utworzyć prostą aplikację do czatowania wideo przy użyciu interfejsu WebRTC API w przeglądarce oraz Cloud Firestore do wywoływania. Aplikacja nazywa się FirebaseRTC i jest prostym przykładem, który pokazuje podstawy tworzenia aplikacji obsługujących WebRTC.
Czego się dowiesz
- Rozpoczynanie rozmowy wideo w aplikacji internetowej przy użyciu WebRTC
- Logowanie do punktu zdalnego przy użyciu Cloud Firestore
Niezbędne elementy
Zanim zaczniesz wykonywać te ćwiczenia z programowania, sprawdź, czy:
- npm, który zwykle jest dołączony do Node.js – węzeł LTS jest zalecany
2. Tworzenie i konfigurowanie projektu Firebase
Tworzenie projektu Firebase
- W konsoli Firebase kliknij Dodaj projekt, a następnie nazwij projekt FirebaseRTC.
Zapamiętaj identyfikator projektu Firebase.
- Kliknij Utwórz projekt.
Aplikacja, którą chcesz utworzyć, korzysta z dwóch usług Firebase dostępnych w internecie:
- Cloud Firestore zapisze uporządkowane dane w chmurze i od razu wyświetli powiadomienie o ich aktualizacji
- Hosting Firebase do hostowania zasobów statycznych i ich wyświetlania
W tym konkretnym ćwiczeniach z programowania masz już skonfigurowany Firebase Hosting w projekcie, który chcesz skopiować. Jednak w Cloud Firestore przeprowadzimy Cię przez konfigurację i włączanie usług za pomocą konsoli Firebase.
Włącz Cloud Firestore
Aplikacja używa Cloud Firestore do zapisywania wiadomości czatu i odbierania nowych wiadomości czatu.
Musisz włączyć Cloud Firestore:
- W sekcji menu programisty w konsoli Firebase kliknij Baza danych.
- W panelu Cloud Firestore kliknij Utwórz bazę danych.
- Wybierz opcję Start in test mode (Rozpocznij w trybie testowym), a po przeczytaniu wyłączenia odpowiedzialności dotyczącego reguł zabezpieczeń kliknij „Enable” (Włącz).
Tryb testowy pozwala na pisanie w bazie danych w dowolnym momencie. Bazę danych zwiększymy później w tym module ćwiczeń.
3. Pobieranie przykładowego kodu
Skopiuj repozytorium GitHub z poziomu wiersza poleceń:
git clone https://github.com/webrtc/FirebaseRTC
Przykładowy kod powinien zostać skopiowany do katalogu FirebaseRTC
.
Upewnij się, że wiersz poleceń jest uruchamiany w tym katalogu:
cd FirebaseRTC
Importowanie aplikacji startowej
Otwórz pliki w edytorze FirebaseRTC
w edytorze i zmień je zgodnie z podanymi niżej instrukcjami. Ten katalog zawiera kod początkowy ćwiczeń z programowania, który składa się z jeszcze niefunkcjonalnej aplikacji WebRTC. Zrobimy to w ramach tych ćwiczeń z programowania.
4. Instalowanie interfejsu wiersza poleceń Firebase
Interfejs wiersza poleceń Firebase umożliwia wyświetlanie aplikacji internetowej lokalnie i wdrażanie aplikacji internetowej w Hostingu Firebase.
- Zainstaluj interfejs wiersza poleceń, uruchamiając następujące polecenie npm:
sh npm -g install firebase-tools
- Sprawdź, czy interfejs wiersza poleceń został prawidłowo zainstalowany, uruchamiając to polecenie:
sh firebase --version
Upewnij się, że interfejs wiersza poleceń Firebase ma wersję 6.7.1 lub nowszą.
- Autoryzuj wiersz poleceń Firebase, uruchamiając następujące polecenie:
sh firebase login
Szablon aplikacji internetowej został skonfigurowany tak, by pobierać konfigurację aplikacji pod kątem Hostingu Firebase z katalogu lokalnego i plików aplikacji. Aby to zrobić, musisz powiązać aplikację z projektem Firebase.
Powiąż aplikację z projektem Firebase, uruchamiając następujące polecenie:
sh firebase use --add
Gdy pojawi się prośba, wybierz identyfikator projektu, a następnie nadaj projektowi Firebase alias.
Alias jest przydatny, jeśli masz wiele środowisk (produkcyjnych, testowych) itp.
Na potrzeby tego ćwiczenia z programowania użyjmy po prostu aliasu default
.
Postępuj zgodnie z pozostałymi instrukcjami w wierszu polecenia.
5. Uruchom serwer lokalny
Możesz już zacząć pracę w naszej aplikacji. Uruchommy aplikację lokalnie.
Uruchom to polecenie wiersza poleceń Firebase:
sh firebase serve --only hosting
Wiersz poleceń powinien zawierać następującą odpowiedź:
hosting: Local server: http://localhost:5000
Korzystamy z emulatora Hostingu Firebase do lokalnego wyświetlania naszej aplikacji. Aplikacja internetowa powinna być teraz dostępna pod adresem http://localhost:5000.
- Otwórz aplikację na stronie http://localhost:5000.
Powinna wyświetlić się kopia projektu FirebaseRTC połączonego z Twoim projektem Firebase.
Aplikacja automatycznie połączyła się z projektem Firebase.
6. Tworzę nowy pokój
W tej aplikacji każda sesja czatu wideo nosi nazwę pokoju. Użytkownik może utworzyć nowy pokój, klikając przycisk w swojej aplikacji. Wygeneruje to identyfikator, którego zdalny członek może użyć, aby dołączyć do tego samego pokoju. Identyfikator jest używany jako klucz w Cloud Firestore dla każdej sali.
Każda sala będzie zawierać RTCSessionDescriptions
zarówno oferty, jak i odpowiedzi, a także dwie osobne kolekcje z kandydatami do ICE od każdej ze stron.
Pierwszym zadaniem jest wdrożenie brakującego kodu na potrzeby tworzenia nowego pokoju z początkową ofertą od dzwoniącego. Otwórz public/app.js
i znajdź komentarz //
Add code for creating a room here
oraz dodaj ten kod:
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!`
W pierwszym wierszu znajduje się obiekt RTCSessionDescription
, który będzie reprezentować ofertę specjalną od rozmówcy. Potem jest ustawiany jako opis lokalny i w końcu zapisywany w nowym obiekcie pokoju w Cloud Firestore.
Następnie będziemy monitorować zmiany w bazie danych i wykryć dodanie odpowiedzi od rozmówcy.
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);
}
});
Poczekaj, aż rozmówca zapisze RTCSessionDescription
jako odpowiedź i ustawi go jako zdalny opis dla rozmówcy
RTCPeerConnection
.
7. Dołączanie do pokoju
Następnym krokiem jest wdrożenie logiki dołączenia do istniejącego pokoju. Użytkownik chce to zrobić, klikając przycisk Dołącz do pokoju i wpisując identyfikator pokoju, do którego chcesz dołączyć. Twoim zadaniem jest zaimplementowanie utworzenia odpowiedzi RTCSessionDescription
i zaktualizowanie odpowiednio pokoju w bazie danych.
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);
W powyższym kodzie zaczynamy od wyodrębnienia oferty od rozmówcy i utworzenia RTCSessionDescription
, który wyznaczymy jako zdalny opis. Następnie tworzymy odpowiedź, ustawiamy ją jako opis lokalny i aktualizujemy bazę danych. Aktualizacja bazy danych uruchomi wywołanie zwrotne onSnapshot
po stronie rozmówcy, co z kolei spowoduje zdalny opis na podstawie odpowiedzi rozmówcy.
To koniec wymiany obiektów RTCSessionDescription
między elementem wywołującym i wywołującym.
8. Zbieranie kandydatów w ICE
Aby rozmówca i osoba, która dzwoniła, mogli się połączyć, musi wymienić ICE, które informują WebRTC o połączeniu ze zdalnym peerem.
Następnym zadaniem jest wdrożenie kodu, który nasłuchuje kandydatów ICE, i dodanie ich do kolekcji w bazie danych. Znajdź funkcję collectIceCandidates
i dodaj ten kod:
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);
}
});
})
}
Ta funkcja pełni dwie funkcje. Zbiera on propozycje ICE z interfejsu API WebRTC i dodaje je do bazy danych, a następnie nasłuchuje dodanych kandydatów ICE ze zdalnego peera i dodaje je do instancji RTCPeerConnection
. Ważne jest, aby słuchać zmian w bazie danych, odfiltrowywać dane, które nie są niczym nowym, ponieważ w przeciwnym razie musielibyśmy wielokrotnie dodawać ten sam zestaw kandydatów do ICE.
9. Podsumowanie
Dzięki temu ćwiczeniu z programowania nauczyliśmy się implementować sygnał dla WebRTC w CloudFirestore, a także jak używać tej funkcji do tworzenia prostej aplikacji do obsługi czatów wideo.
Więcej informacji znajdziesz w tych materiałach: