1. 引言
在本程式碼研究室中,您將瞭解如何使用瀏覽器中的 WebRTC API 和 Cloud Firestore 建立簡易的視訊通訊應用程式。這個應用程式稱為 FirebaseRTC,可做為簡易範例,讓您瞭解如何建構支援 WebRTC 的應用程式。
課程內容
- 使用 WebRTC 在網頁應用程式啟動視訊通話
- 使用 Cloud Firestore 向遠端方進行訊號
軟硬體需求
開始進行這個程式碼研究室之前,請確認您已安裝下列項目:
- 通常與 Node.js 搭配使用的 npm - 建議使用節點 LTS
2. 建立及設定 Firebase 專案
建立 Firebase 專案
- 在 Firebase 主控台中,按一下 [Add project] (新增專案),並為 Firebase 專案命名:FirebaseRTC。
記住 Firebase 專案的專案 ID。
- 按一下 [建立專案]。
您要建立的應用程式會使用兩種網路上提供的 Firebase 服務:
- Cloud Firestore 可將結構化資料儲存至雲端,並在資料更新時立即取得通知
- 使用 Firebase 託管功能來提供及提供靜態素材資源
在這個特定的程式碼研究室中,您已經在要複製的專案中設定 Firebase 託管。但在 Cloud Firestore 中,我們會逐步引導您使用 Firebase 主控台進行設定及啟用服務。
啟用 Cloud Firestore
這個應用程式使用 Cloud Firestore 儲存即時通訊訊息,並接收新的即時通訊訊息。
您必須啟用 Cloud Firestore:
- 在 Firebase 主控台選單中,按一下 [資料庫]。
- 按一下 Cloud Firestore 窗格中的 [Create database] (建立資料庫)。
- 選取 [Start in test mode] (以測試模式啟動) 選項,閱讀安全性規則的免責聲明後,按一下 [Enable] (啟用)。
在測試模式下,您可以在開發期間自由寫入資料庫。在程式碼研究室中,我們會進一步確保資料庫的安全性。
3. 取得範例程式碼
從指令列複製 GitHub 存放區:
git clone https://github.com/webrtc/FirebaseRTC
範例程式碼應複製到 FirebaseRTC
目錄中。請確認您的指令列從現在開始執行:
cd FirebaseRTC
匯入啟動應用程式
在編輯器中開啟「FirebaseRTC
」中的檔案,並按照以下操作說明進行變更。這個目錄包含程式碼研究室的開始程式碼,該程式碼是由尚未實際運作的 WebRTC 應用程式組成。我們會在這個程式碼研究室中讓程式碼順利運作。
4. 安裝 Firebase 指令列介面
Firebase 指令列介面 (CLI) 可讓您在本機端提供網路應用程式,並將網頁應用程式部署到 Firebase 託管。
- 執行下列指令來安裝 CLI:
sh npm -g install firebase-tools
- 執行下列指令來確認 CLI 已正確安裝:
sh firebase --version
請確認 Firebase CLI 版本為 6.7.1 以上版本。
- 執行下列指令來授權 Firebase CLI:
sh firebase login
您已設定網頁應用程式範本,藉此提取 Firebase 的應用程式設定 從應用程式的本機目錄和檔案提取設定。但若要這麼做, 您必須為應用程式與 Firebase 專案建立關聯
執行下列指令來連結應用程式與 Firebase 專案:
sh firebase use --add
系統顯示提示時,請選取您的專案 ID,並提供 Firebase 專案的別名。
如果您有多個環境 (實際工作環境、執行環境等),就很適合使用別名。不過,在這個程式碼研究室中,我們只是使用 default
的別名。
按照指令列中其餘的操作說明進行。
5. 執行本機伺服器
你現在可以開始透過我們的應用程式了!讓我們在本機執行應用程式!
執行下列 Firebase CLI 指令:
sh firebase serve --only hosting
您的指令列應會顯示下列回應:
hosting: Local server: http://localhost:5000
我們使用 Firebase 託管模擬器在本地提供應用程式。網頁應用程式現在應於 http://localhost:5000 提供。
- 在 http://localhost:5000 開啟您的應用程式。
您應該會看到已連結到 Firebase 專案的 FirebaseRTC 複本。
應用程式已自動連結至您的 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 Firestore 實作 WebRTC 信號,以及如何利用這項功能建立簡單的視訊通訊應用程式。
詳情請參閱下列資源: