Firebase + WebRTC Codelab

1. מבוא

ב-Codelab הזה תלמדו איך לפתח אפליקציה פשוטה לווידאו צ'אט באמצעות את ה-WebRTC API בדפדפן ואת Cloud Firestore לצורך אותות. נקרא FirebaseRTC והוא פועל כדוגמה פשוטה שילמדו אתם יכולים להיעזר ביסודות של בניית אפליקציות שמופעלות על ידי WebRTC.

מה תלמדו

  • התחלת שיחת וידאו באפליקציית אינטרנט באמצעות WebRTC
  • איתות לצד המרוחק באמצעות Cloud Firestore

למה תזדקק?

לפני שמתחילים ב-Codelab הזה, צריך לוודא שהתקנתם את:

  • npm שבדרך כלל מגיע עם Node.js – מומלץ להשתמש ב-Node LTS

2. יצירה והגדרה של פרויקט Firebase

יוצרים פרויקט Firebase

  1. במסוף Firebase לוחצים על 'הוספה'. ולתת שם לפרויקט FirebaseRTC.

חשוב לזכור את מזהה הפרויקט של פרויקט Firebase.

  1. לוחצים על Create project.

האפליקציה שאתם מתכוונים לפתח משתמשת בשני שירותי Firebase זמינים באינטרנט:

  • Cloud Firestore כדי לשמור נתונים מובְנים בענן ולקבל מידע באופן מיידי התראה כשהנתונים מתעדכנים
  • אירוח ב-Firebase לאירוח ולהצגה של נכסים סטטיים

עבור ה-Codelab הספציפי הזה, כבר הגדרתם אירוח ב-Firebase שרוצים לשכפל. עם זאת, ב-Cloud Firestore, נסביר ההגדרה וההפעלה של השירותים באמצעות מסוף Firebase.

הפעלת Cloud Firestore

האפליקציה משתמשת ב-Cloud Firestore כדי לשמור את הודעות הצ'אט ולקבל שיחות חדשות הודעות.

צריך להפעיל את Cloud Firestore:

  1. בקטע 'פיתוח' בתפריט של מסוף Firebase, לוחצים על 'מסד נתונים'.
  2. לוחצים על Create dataset בחלונית Cloud Firestore.
  3. בוחרים באפשרות הפעלה במצב בדיקה, ולוחצים על 'הפעלה' אחרי שקוראים את כתב ויתור לגבי כללי האבטחה.

מצב הבדיקה מבטיח שתהיה לך אפשרות לכתוב בחופשיות למסד הנתונים במהלך הפיתוח. בהמשך נשפר את האבטחה של מסד הנתונים שלנו ב-Codelab הזה.

3. לקבלת הקוד לדוגמה

משכפלים את המאגר של GitHub משורת הפקודה:

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

הקוד לדוגמה אמור להיות משוכפל לספרייה FirebaseRTC. חשוב לוודא ששורת הפקודה רצה מהספרייה הזו מעכשיו:

cd FirebaseRTC

ייבוא של האפליקציה לתחילת פעולה

פותחים את הקבצים ב-FirebaseRTC בעורך ומשנים אותם בהתאם את ההוראות שבהמשך. הספרייה הזו מכילה את קוד ההתחלה עבור Codelab, שמורכב מאפליקציית WebRTC שעדיין לא פעילה. אנחנו נבצע את זה פונקציונליות במהלך ה-Codelab הזה.

4. התקנת ממשק שורת הפקודה של Firebase

ממשק שורת הפקודה של Firebase (CLI) מאפשר להציג את אפליקציית האינטרנט שלכם. באופן מקומי ולפרוס את אפליקציית האינטרנט באירוח Firebase.

  1. כדי להתקין את ה-CLI, מריצים את פקודת ה-npm הבאה: sh npm -g install firebase-tools
  1. כדי לוודא שה-CLI הותקן כראוי, מריצים את הפקודה הבאה הפקודה: sh firebase --version

מוודאים שהגרסה של Firebase CLI היא גרסה 6.7.1 ואילך.

  1. כדי לאשר את ה-CLI של Firebase, מריצים את הפקודה הבאה: sh firebase login

הגדרת את התבנית של אפליקציית האינטרנט כדי לשלוף את ההגדרות של האפליקציה ל-Firebase אירוח מהספרייה המקומית והקבצים של האפליקציה. אבל כדי לעשות את זה, לשייך את האפליקציה לפרויקט Firebase.

  1. כדי לשייך את האפליקציה לפרויקט Firebase, מריצים את הפקודה הבאה הפקודה: sh firebase use --add

  2. כשתוצג הבקשה, בוחרים את מזהה הפרויקט ומקצים לפרויקט Firebase כתובת אימייל חלופית.

כתובת אימייל חלופית שימושית אם יש לכם כמה סביבות (ייצור, Staging וכו'). עם זאת, עבור ה-Codelab הזה, נשתמש רק בכינוי של default.

  1. מבצעים את שאר ההוראות בשורת הפקודה.

5. הפעלת השרת המקומי

עכשיו אפשר להתחיל לעבוד על האפליקציה שלנו! רוצה להפעיל את האפליקציה באופן מקומי?

  1. מריצים את הפקודה הבאה ב-CLI של Firebase: sh firebase serve --only hosting

  2. בשורת הפקודה אמורה להופיע התגובה הבאה: hosting: Local server: http://localhost:5000

אנחנו משתמשים באמולטור אירוח ב-Firebase כדי לספק שירות לאפליקציה שלנו באופן מקומי. באפליקציית האינטרנט אמורות להיות זמינות בכתובת http://localhost:5000.

  1. פותחים את האפליקציה בכתובת http://localhost:5000.

אמור להופיע עותק של FirebaseRTC שחובר אל פרויקט Firebase.

האפליקציה מחוברת באופן אוטומטי לפרויקט Firebase שלכם.

6. יצירת חדר חדש

באפליקציה הזו, כל הפעלת וידאו צ'אט נקראת חדר. המשתמש יכול ליצור חדר חדש באמצעות לחיצה על לחצן באפליקציה. הפעולה הזו תיצור מזהה שהצד השני בשיחה יוכל להשתמש בו כדי להצטרף לאותו חדר. המזהה משמש כמפתח ב-Cloud Firestore לכל חדר.

כל חדר מכיל את RTCSessionDescriptions של המבצע וגם של וגם שני אוספים נפרדים עם מועמדים מסוג ICE מכל מפלגה.

המשימה הראשונה שלכם היא להטמיע את הקוד החסר ליצירת חדר חדש עם והצעה ראשונית מהמתקשר. פותחים את public/app.js, מחפשים את התגובה // Add code for creating a room here ומוסיפים את הקוד הבא:

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

השורה הראשונה יוצרת RTCSessionDescription שייצג את המבצע מהמתקשר. לאחר מכן הוא מוגדר כתיאור מקומי, ולבסוף נכתב לאובייקט החדר החדש ב-Cloud Firestore.

בשלב הבא אנחנו מקשיבים לשינויים שבוצעו במסד הנתונים ומגלים אם ניתנה תשובה המתקשר נוסף.

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

הפעולה הזו תמתין עד שהמקבל יכתוב את המסמך RTCSessionDescription עבור לענות ולהגדיר זאת כתיאור מרחוק של המתקשר RTCPeerConnection.

7. הצטרפות לחדר

השלב הבא הוא להטמיע את הלוגיקה להצטרפות לחדר קיים. המשתמש/ת כדי לעשות את זה, לוחצים על הלחצן הצטרפות לחדר ומזינים את המזהה של החדר. להצטרף אליה. המשימה שלכם היא להטמיע את היצירה של RTCSessionDescription לתשובה ולעדכן את החדר במסד הנתונים. בהתאם.

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

בקוד שלמעלה, בתור התחלה, חילוץ המבצע מהמתקשר ויצירת RTCSessionDescription שהגדרנו כתיאור מרחוק. בשלב הבא אנחנו יוצרים התשובה, מגדירים אותה כתיאור מקומי ומעדכנים את מסד הנתונים. העדכון של מסד הנתונים יפעיל את הקריאה החוזרת של onSnapshot בצד המתקשר, בתורו, יגדיר את התיאור מרחוק בהתאם לתשובה מהמתקשר. הושלמה ההחלפה של RTCSessionDescription האובייקטים בין המתקשר והמקבל.

8. איסוף מועמדים ל-ICE

כדי שהמתקשר/ת יוכל/ה להתחבר זה לזה, הם צריכים גם: מועמדים מסוג ICE שמסבירים ל-WebRTC איך להתחבר לאפליקציה המרוחקת. המשימה הבאה היא להטמיע את הקוד שמאזין למועמדי ICE ומוסיף אותם לאוסף במסד הנתונים. מחפשים את הפונקציה collectIceCandidates ומוסיפים את הקוד הבא:

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

הפונקציה הזו מבצעת שתי פעולות. היא אוספת מועמדי ICE מ-WebRTC API וגם מוסיף אותם למסד הנתונים ומאזינים למועמדי ICE שנוספו מרחוק. הרשת השכנה ומוסיפה אותם למכונה RTCPeerConnection. חשוב לציין להקשיב לשינויים במסד הנתונים כדי לסנן כל מה שלא חדש, כי אחרת היינו מוסיפים את אותה קבוצה של מועמדי ICE שוב ושוב, שוב.

9. סיכום

ב-Codelab הזה למדת איך להטמיע אותות עבור WebRTC באמצעות Cloud Firestore, ואיך להשתמש בו ליצירת וידאו צ'אט פשוט תרגום מכונה.

מידע נוסף זמין במקורות המידע הבאים:

  1. קוד מקור של FirebaseRTC
  2. דוגמאות WebRTC
  3. Cloud Firestore