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 ให้คลิก "เพิ่ม" แล้วตั้งชื่อโปรเจ็กต์ Firebase ซึ่งก็คือ FirebaseRTC

จำรหัสโปรเจ็กต์สําหรับโปรเจ็กต์ Firebase

  1. คลิกสร้างโปรเจ็กต์

แอปพลิเคชันที่คุณกำลังจะสร้างใช้บริการ Firebase 2 บริการที่มี บนเว็บ

  • Cloud Firestore เพื่อบันทึก Structured Data บนระบบคลาวด์และเริ่มต้นใช้งานทันที การแจ้งเตือนเมื่อข้อมูลได้รับการอัปเดต
  • โฮสติ้งของ Firebase เพื่อโฮสต์และแสดงเนื้อหาแบบคงที่

สำหรับ Codelab ที่ระบุนี้ คุณได้กำหนดค่าโฮสติ้งของ Firebase ใน ที่คุณจะโคลน อย่างไรก็ตาม สำหรับ Cloud Firestore เราจะแนะนำคุณ การกำหนดค่าและการเปิดใช้บริการโดยใช้คอนโซล Firebase

เปิดใช้ Cloud Firestore

แอปใช้ Cloud Firestore เพื่อบันทึกข้อความแชทและรับแชทใหม่ ข้อความ

คุณจะต้องเปิดใช้ Cloud Firestore

  1. ในส่วน Develop ของเมนูคอนโซล Firebase ให้คลิกฐานข้อมูล
  2. คลิกสร้างฐานข้อมูลในแผง 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 เป็น v6.7.1 ขึ้นไป

  1. ให้สิทธิ์ Firebase CLI โดยเรียกใช้คำสั่งต่อไปนี้ sh firebase login

คุณได้ตั้งค่าเทมเพลตเว็บแอปให้ดึงการกำหนดค่าของแอปสำหรับ Firebase แล้ว โฮสติ้งจากไดเรกทอรีและไฟล์ในเครื่องของแอป แต่หากต้องการทำเช่นนี้ คุณจะต้อง เชื่อมโยงแอปกับโปรเจ็กต์ Firebase ของคุณ

  1. เชื่อมโยงแอปกับโปรเจ็กต์ Firebase โดยการเรียกใช้โค้ดต่อไปนี้ คำสั่ง: sh firebase use --add

  2. เมื่อได้รับข้อความแจ้ง ให้เลือกรหัสโปรเจ็กต์ แล้วตั้งชื่อโปรเจ็กต์ Firebase ชื่อแทน

ชื่อแทนจะมีประโยชน์หากคุณมีสภาพแวดล้อมหลายอย่าง (การผลิต การทดลองใช้ ฯลฯ) แต่สำหรับ Codelab นี้ โปรดใช้ชื่อแทนของ default

  1. ทําตามวิธีการที่เหลือในบรรทัดคำสั่ง

5. เรียกใช้เซิร์ฟเวอร์ภายใน

คุณพร้อมที่จะเริ่มทำงานในแอปของเราแล้ว มาเรียกใช้แอปในเครื่องกัน

  1. เรียกใช้คำสั่ง Firebase CLI ต่อไปนี้ 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 สำหรับทั้งข้อเสนอและ รวมถึงคอลเล็กชัน 2 ชุดที่มีผู้สมัครจาก 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ที่เราตั้งค่าเป็นคำอธิบายระยะไกล ต่อไป เราจะสร้าง คำตอบ กำหนดเป็นคำอธิบายในเครื่อง และอัปเดตฐานข้อมูล ข้อมูลอัปเดต ของฐานข้อมูลจะทริกเกอร์ Callback 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);
            }
        });
    })
}

ฟังก์ชันนี้ทำหน้าที่ 2 อย่าง รวบรวมตัวเลือก ICE จาก WebRTC API และ เพิ่มไปยังฐานข้อมูลและรอฟังตัวเลือก ICE ที่เพิ่มจากรีโมต เพียร์และเพิ่มไปยังอินสแตนซ์ RTCPeerConnection สิ่งสำคัญก็คือ ฟังการเปลี่ยนแปลงฐานข้อมูลเพื่อกรองสิ่งที่ไม่ใช่การเพิ่มใหม่ เนื่องจากเราอาจเพิ่มชุดตัวเลือก ICE เดิมซ้ำแล้วซ้ำอีก อีกครั้ง

9. บทสรุป

คุณได้เรียนรู้วิธีใช้งานการส่งสัญญาณสำหรับ WebRTC โดยใช้ Cloud ใน Codelab นี้แล้ว Firestore รวมถึงวิธีใช้ไฟล์ดังกล่าวเพื่อสร้างวิดีโอแชทง่ายๆ แอปพลิเคชัน

ดูข้อมูลเพิ่มเติมได้ในแหล่งข้อมูลต่อไปนี้

  1. ซอร์สโค้ด FirebaseRTC
  2. ตัวอย่าง WebRTC
  3. Cloud Firestore