Firebase + WebRTC Codelab

1. บทนำ

ใน Codelab นี้ คุณจะได้ดูวิธีสร้างแอปพลิเคชันวิดีโอแชทแบบง่ายๆ โดยใช้ WebRTC API ในเบราว์เซอร์และ Cloud Firestore สําหรับการส่งสัญญาณ แอปพลิเคชันนี้เรียกว่า FirebaseRTC ซึ่งทําหน้าที่เป็นตัวอย่างง่ายๆ ที่จะสอนพื้นฐานการสร้างแอปพลิเคชันที่เปิดใช้ WebRTC

สิ่งที่คุณจะได้เรียนรู้

  • การเริ่มต้นวิดีโอคอลในเว็บแอปพลิเคชันโดยใช้ WebRTC
  • ส่งสัญญาณไปยังบุคคลอื่นจากระยะไกลโดยใช้ Cloud Firestore

สิ่งที่ต้องมี

ก่อนที่จะเริ่ม Codelab นี้ โปรดตรวจสอบว่าคุณได้ติดตั้งแล้ว

  • npm ซึ่งมักมาพร้อมกับ Node.js - ขอแนะนําให้ใช้ LTS LTS

2. สร้างและตั้งค่าโปรเจ็กต์ Firebase

สร้างโปรเจ็กต์ Firebase

  1. ในคอนโซล Firebase ให้คลิกเพิ่มโปรเจ็กต์ แล้วตั้งชื่อโปรเจ็กต์ Firebase ว่า FirebaseRTC

จดจํารหัสโปรเจ็กต์ Firebase ของคุณ

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

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

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

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

เปิดใช้ Cloud Firestore

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

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

  1. ในส่วน "พัฒนา" ของคอนโซล 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 Command Line Interface (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 ที่เราตั้งค่าไว้เป็นคําอธิบายระยะไกล จากนั้นให้สร้างคําตอบโดยตั้งเป็นคําอธิบายในเครื่องและอัปเดตฐานข้อมูล การอัปเดตฐานข้อมูลจะเป็นการเรียกโค้ดเรียกกลับของ 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());
                peerConneciton.addIceCandidate(candidate);
            }
        });
    })
}

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

9. บทสรุป

ใน Codelab นี้ คุณจะได้ดูวิธีใช้สัญญาณสําหรับ WebRTC โดยใช้ Cloud Firestore และวิธีใช้วิธีสร้างแอปพลิเคชันวิดีโอแชทแบบง่ายๆ

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

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