Firebase + WebRTC 程式碼研究室

1. 簡介

在本程式碼研究室中,您將瞭解如何使用 以便傳送訊號 FirebaseRTC 的例子 ,瞭解建構啟用 WebRTC 應用程式的基本概念。

課程內容

  • 使用 WebRTC 在網頁應用程式發起視訊通話
  • 使用 Cloud Firestore 向遠端方發出訊號

軟硬體需求

開始本程式碼研究室之前,請確認您已安裝:

  • 通常隨附 Node.js 的 npm,建議採用 Node LTS

2. 建立及設定 Firebase 專案

建立 Firebase 專案

  1. 在 Firebase 控制台中按一下「新增」 ,然後將 Firebase 專案命名為 FirebaseRTC

記下 Firebase 專案的專案 ID。

  1. 按一下「建立專案」。

您要建構的應用程式採用兩種 Firebase 服務 網頁:

  • 有了 Cloud Firestore,在 Cloud 中儲存結構化資料並即時取得 資料更新時收到通知
  • 使用 Firebase 託管服務來託管和提供靜態資產

在本程式碼研究室中,您已在以下位置設定 Firebase 託管: 。不過,我們會逐步指導 Cloud Firestore 使用 Firebase 控制台進行設定和啟用服務。

啟用 Cloud Firestore

應用程式使用 Cloud Firestore 儲存即時通訊訊息及接收新的對話 訊息。

您必須啟用 Cloud Firestore:

  1. 在 Firebase 控制台選單的「開發」專區中,按一下「資料庫」。
  2. 按一下 Cloud Firestore 窗格中的「建立資料庫」
  3. 選取「以測試模式啟動」選項,閱讀完 安全性規則免責事項。

測試模式可確保您在開發期間能自由寫入資料庫。 在本程式碼研究室中,我們稍後會提高資料庫的安全性。

3. 取得範例程式碼

從指令列複製 GitHub 存放區:

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

程式碼範例應已複製到 FirebaseRTC 目錄中。 確定您的指令列從現在起會從以下目錄執行:

cd FirebaseRTC

匯入範例應用程式

在編輯器中開啟 FirebaseRTC 中的檔案,並根據 操作說明。這個目錄包含 程式碼研究室包含目前還沒有人運作的 WebRTC 應用程式。我們是 所有功能。

4. 安裝 Firebase 指令列介面

透過 Firebase 指令列介面 (CLI),即可提供網頁應用程式 並將網頁應用程式部署至 Firebase 託管。

  1. 執行下列 npm 指令安裝 CLI: sh npm -g install firebase-tools
,瞭解如何調查及移除這項存取權。
  1. 執行下列指令,確認 CLI 已正確安裝 指令: sh firebase --version

確認 Firebase CLI 的版本為 6.7.1 以上版本。

  1. 執行下列指令來授權 Firebase CLI: sh firebase login

您已設定網頁應用程式範本,以便提取 Firebase 的應用程式設定 由應用程式的本機目錄和檔案代管。但要做到這一點 連結應用程式與 Firebase 專案

  1. 如要將應用程式與 Firebase 專案建立關聯,請執行下列指令, 指令: sh firebase use --add

  2. 系統顯示提示時,請選取專案 ID,然後為 Firebase 專案 別名。

如果有多個環境 (正式環境、測試環境等),就很適合使用別名。 不過,在本程式碼研究室中,我們直接使用 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 開啟應用程式。

您應該會看到與 Firebase 專案。

應用程式已自動連結至您的 Firebase 專案。

6. 建立新房間

在此應用程式中,每個視訊通訊工作階段稱為一個房間。使用者可建立 以建立新房間系統會產生 ID 方便遠端派對加入同一個房間ID 會當做鍵 查看每個房間的 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. 加入聊天室

下一步是實作加入現有會議室的邏輯。該使用者 方法是按一下 [加入聊天室] 按鈕,然後輸入會議室 ID 才能加入。您的任務是實作 回答 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);
            }
        });
    })
}

這個函式會執行兩項作業。它會從 WebRTC API 收集 ICE 候選項目, 只要將這些候選項目新增至資料庫,並從遠端監聽新增的 ICE 候選鍵 並新增至其 RTCPeerConnection 執行個體。請務必確保 監聽資料庫變更並濾除非新增的內容 因為我們不然會將同一組 ICE 候選項目加入 可以選取「重新建立」,再次生成新的提示

9. 結論

在本程式碼研究室中,您已瞭解如何使用 Cloud 為 WebRTC 實作信號 以及如何使用 Firestore 和 Cloud Firestore 應用程式。

詳情請參閱下列資源:

  1. FirebaseRTC 原始碼
  2. WebRTC 範例
  3. Cloud Firestore