Codelab su Firebase e WebRTC

1. Introduzione

In questo codelab, imparerai a creare una semplice applicazione per video chat utilizzando l'API WebRTC nel tuo browser e Cloud Firestore per la segnalazione. La un'applicazione si chiama FirebaseRTC, è un semplice esempio che insegnerà nozioni di base sulla creazione di applicazioni abilitate per WebRTC.

Obiettivi didattici

  • Avvio di una videochiamata in un'applicazione web utilizzando WebRTC
  • Segnalazione alla parte remota mediante Cloud Firestore

Che cosa ti serve

Prima di iniziare questo codelab, assicurati di aver installato:

  • npm, che in genere viene fornito con Node.js; è consigliato Node LTS

2. Crea e configura un progetto Firebase

Crea un progetto Firebase

  1. Nella console Firebase, fai clic su Aggiungi denomina il progetto Firebase FirebaseRTC.

Ricorda l'ID del progetto Firebase.

  1. Fai clic su Crea progetto.

L'applicazione che creerai utilizza due servizi Firebase disponibili sul web:

  • Cloud Firestore per salvare i dati strutturati su Cloud e ottenere istantaneamente una notifica quando i dati vengono aggiornati
  • Firebase Hosting per ospitare e pubblicare i tuoi asset statici

Per questo codelab specifico, hai già configurato Firebase Hosting nella progetto che clonerai. Tuttavia, per Cloud Firestore, ti guideremo attraverso la configurazione e l'abilitazione dei servizi tramite la console Firebase.

Abilita Cloud Firestore

L'app utilizza Cloud Firestore per salvare i messaggi di chat e riceverne di nuovi messaggi.

Dovrai abilitare Cloud Firestore:

  1. Nella sezione Sviluppo del menu della console Firebase, fai clic su Database.
  2. Fai clic su Crea database nel riquadro Cloud Firestore.
  3. Seleziona l'opzione Avvia in modalità di test, quindi fai clic su Attiva dopo aver letto le disclaimer sulle regole di sicurezza.

La modalità di test garantisce di poter scrivere liberamente nel database durante lo sviluppo. Renderemo il nostro database più sicuro più avanti in questo codelab.

3. recupera il codice campione

Clona il repository GitHub dalla riga di comando:

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

Il codice campione dovrebbe essere stato clonato nella directory FirebaseRTC. D'ora in poi, assicurati che la riga di comando venga eseguita da questa directory:

cd FirebaseRTC

Importa l'app iniziale

Apri i file in FirebaseRTC nell'editor e modificali in base a le istruzioni riportate di seguito. Questa directory contiene il codice iniziale per che consiste in un'app WebRTC non ancora funzionante. Ce la faremo funzionali in tutto questo codelab.

4. Installa l'interfaccia a riga di comando di Firebase

L'interfaccia a riga di comando (CLI) di Firebase ti consente di pubblicare la tua app web in locale ed eseguire il deployment della tua app web su Firebase Hosting.

  1. Installa l'interfaccia a riga di comando eseguendo questo comando npm: sh npm -g install firebase-tools
di Gemini Advanced.
  1. Verifica che l'interfaccia a riga di comando sia stata installata correttamente eseguendo questo comando : sh firebase --version

Assicurati che la versione dell'interfaccia a riga di comando di Firebase sia v6.7.1 o successiva.

  1. Autorizza l'interfaccia a riga di comando di Firebase eseguendo questo comando: sh firebase login

Hai impostato il modello di app web in modo da estrarre la configurazione dell'app per Firebase Hosting dalla directory locale e dai file dell'app. Ma per farlo, devi associare la tua app al progetto Firebase.

  1. Associa la tua app al progetto Firebase eseguendo quanto segue : sh firebase use --add

  2. Quando richiesto, seleziona l'ID progetto, quindi assegna al progetto Firebase alias.

Un alias è utile se disponi di più ambienti (produzione, gestione temporanea e così via). Tuttavia, per questo codelab, utilizziamo solo l'alias di default.

  1. Segui le istruzioni rimanenti nella riga di comando.

5. Esegui il server locale

Sei pronto per iniziare a lavorare sulla nostra app. Esegui l'app in locale.

  1. Esegui questo comando dell'interfaccia a riga di comando di Firebase: sh firebase serve --only hosting

  2. La riga di comando dovrebbe visualizzare la seguente risposta: hosting: Local server: http://localhost:5000

Stiamo utilizzando l'emulatore Firebase Hosting per pubblicare la nostra app localmente. L'app web dovrebbe essere ora disponibile all'indirizzo http://localhost:5000.

  1. Apri l'app all'indirizzo http://localhost:5000.

Dovresti vedere la copia di FirebaseRTC collegata al tuo progetto Firebase.

L'app si è connessa automaticamente al tuo progetto Firebase.

6. Creazione di una nuova stanza

In questa applicazione, ogni sessione di video chat è chiamata stanza virtuale. Un utente può creare in una nuova stanza virtuale facendo clic su un pulsante nell'applicazione. Questo genererà un ID che il gruppo remoto può utilizzare per entrare nella stessa stanza. L'ID è utilizzato come chiave in Cloud Firestore per ogni sala.

Ogni camera conterrà RTCSessionDescriptions sia per l'offerta sia per oltre a due raccolte separate con candidati ICE di ogni partito.

La tua prima attività consiste nell'implementare il codice mancante per creare una nuova stanza virtuale con l'offerta iniziale del chiamante. Apri public/app.js, trova il commento // Add code for creating a room here e aggiungi il seguente codice:

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!`

La prima riga crea un RTCSessionDescription che rappresenterà l'offerta dal chiamante. Questa viene quindi impostata come descrizione locale e infine scritta al nuovo oggetto room in Cloud Firestore.

Successivamente, ascolteremo le modifiche apportate al database e rileveremo quando una risposta il destinatario della chiamata è stato aggiunto.

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

Questa operazione attende che il destinatario scriva il RTCSessionDescription per il e impostarla come descrizione remota del chiamante RTCPeerConnection.

7. Partecipazione a una stanza virtuale

Il passaggio successivo è implementare la logica per partecipare a una stanza virtuale esistente. L'utente Per farlo, fai clic sul pulsante Partecipa alla stanza virtuale e inserisci l'ID della stanza per partecipare. Il tuo compito è implementare la creazione RTCSessionDescription per la risposta e aggiorna la stanza nel database di conseguenza.

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

Nel codice riportato sopra, iniziamo estraendo l'offerta dal chiamante e creando un RTCSessionDescription che abbiamo impostato come descrizione remota. Ora creiamo la risposta, impostarla come descrizione locale e aggiornare il database. Aggiornamento del database attiverà il callback onSnapshot sul lato chiamante, a sua volta, imposterà la descrizione remota in base alla risposta del chiamante. Viene completato lo scambio degli oggetti RTCSessionDescription tra sia il chiamante che il chiamante.

8. Raccogli i candidati ICE

Prima che il chiamante e il chiamante possano connettersi tra loro, devono Scambio di candidati ICE che indicano a WebRTC come connettersi al peer remoto. L'attività successiva consiste nell'implementare il codice che ascolti i candidati ICE e aggiunge in una raccolta nel database. Trova la funzione collectIceCandidates e aggiungi il seguente codice:

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

Questa funzione svolge due operazioni. Raccoglie candidati ICE dall'API WebRTC e li aggiunge al database e ascolta i candidati ICE aggiunti dal telecomando e li aggiunge alla rispettiva istanza RTCPeerConnection. È importante quando l'ascolto delle modifiche al database per filtrare tutto ciò che non è una nuova aggiunta, in quanto altrimenti avremmo aggiunto sempre lo stesso gruppo di candidati ICE di nuovo.

9. Conclusione

In questo codelab hai imparato come implementare la segnalazione per WebRTC utilizzando Cloud Firestore e spiega come utilizzarlo per creare una semplice videochiamata un'applicazione.

Per saperne di più, consulta le seguenti risorse:

  1. Codice sorgente FirebaseRTC
  2. Esempi WebRTC
  3. Cloud Firestore