1. Введение
В этой лабораторной работе вы узнаете, как создать простое приложение для видеочата, используя WebRTC API в вашем браузере и Cloud Firestore для передачи сигналов. Приложение называется FirebaseRTC и работает как простой пример, который научит вас основам создания приложений с поддержкой WebRTC.
Что вы узнаете
- Инициация видеозвонка в веб-приложении с использованием WebRTC
- Сигнализация удаленной стороне с помощью Cloud Firestore
Что вам понадобится
Перед запуском этой кодлабы убедитесь, что вы установили:
- npm, который обычно поставляется с Node.js — рекомендуется Node LTS
2. Создайте и настройте проект Firebase
Создайте проект Firebase
- В консоли Firebase нажмите «Добавить проект», затем назовите проект Firebase FirebaseRTC.
Запомните идентификатор проекта для вашего проекта Firebase.
- Щелкните Создать проект.
Приложение, которое вы собираетесь создать, использует две службы Firebase, доступные в Интернете:
- Cloud Firestore для сохранения структурированных данных в облаке и получения мгновенных уведомлений при обновлении данных.
- Хостинг Firebase для размещения и обслуживания ваших статических ресурсов
Для этой конкретной кодовой лаборатории вы уже настроили Firebase Hosting в проекте, который будете клонировать. Однако для Cloud Firestore мы проведем вас через настройку и включение служб с помощью консоли Firebase.
Включить облачное хранилище Firestore
Приложение использует Cloud Firestore для сохранения сообщений чата и получения новых сообщений чата.
Вам нужно включить Cloud Firestore:
- В разделе «Разработка» меню консоли Firebase нажмите «База данных».
- Нажмите Создать базу данных на панели Cloud Firestore.
- Выберите параметр « Начать в тестовом режиме », затем нажмите «Включить» после прочтения заявления об отказе от ответственности в отношении правил безопасности.
Тестовый режим гарантирует, что вы можете свободно писать в базу данных во время разработки. Мы сделаем нашу базу данных более безопасной позже в этой лаборатории кода.
3. Получите пример кода
Клонируйте репозиторий GitHub из командной строки:
git clone https://github.com/webrtc/FirebaseRTC
Пример кода должен был быть клонирован в каталог FirebaseRTC
. Убедитесь, что с этого момента ваша командная строка запускается из этого каталога:
cd FirebaseRTC
Импортировать стартовое приложение
Откройте файлы в FirebaseRTC
в своем редакторе и измените их в соответствии с приведенными ниже инструкциями. Этот каталог содержит начальный код для лаборатории кода, который состоит из еще не работающего приложения WebRTC. Мы сделаем его функциональным в этой кодлабе.
4. Установите интерфейс командной строки Firebase
Интерфейс командной строки Firebase (CLI) позволяет вам обслуживать ваше веб-приложение локально и развертывать его на хостинге Firebase.
- Установите CLI, выполнив следующую команду npm:
sh npm -g install firebase-tools
- Убедитесь, что CLI установлен правильно, выполнив следующую команду:
sh firebase --version
Убедитесь, что версия интерфейса командной строки Firebase — 6.7.1 или более поздняя.
- Авторизуйте интерфейс командной строки Firebase, выполнив следующую команду:
sh firebase login
Вы настроили шаблон веб-приложения, чтобы получить конфигурацию вашего приложения для Firebase Hosting из локального каталога и файлов вашего приложения. Но для этого вам нужно связать свое приложение с вашим проектом Firebase.
Свяжите свое приложение с проектом Firebase, выполнив следующую команду:
sh firebase use --add
При появлении запроса выберите идентификатор проекта, а затем дайте псевдоним проекту Firebase.
Псевдоним полезен, если у вас несколько сред (производственная, промежуточная и т. д.). Однако для этой кодлабы давайте просто воспользуемся псевдонимом default
.
Следуйте оставшимся инструкциям в вашей командной строке.
5. Запустите локальный сервер
Вы готовы начать работу над нашим приложением! Давайте запустим приложение локально!
Запустите следующую команду Firebase CLI:
sh firebase serve --only hosting
Ваша командная строка должна отобразить следующий ответ:
hosting: Local server: http://localhost:5000
Мы используем эмулятор Firebase Hosting для локального обслуживания нашего приложения. Теперь веб-приложение должно быть доступно по адресу http://localhost:5000.
- Откройте свое приложение по адресу 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());
peerConneciton.addIceCandidate(candidate);
}
});
})
}
Эта функция делает две вещи. Он собирает кандидатов ICE из API WebRTC и добавляет их в базу данных, а также прослушивает добавленных кандидатов ICE от удаленного узла и добавляет их в свой экземпляр RTCPeerConnection
. При прослушивании изменений в базе данных важно отфильтровывать все, что не является новым дополнением, поскольку в противном случае мы бы снова и снова добавляли один и тот же набор кандидатов ICE.
9. Заключение
В этой лабораторной работе вы узнали, как реализовать сигнализацию для WebRTC с помощью Cloud Firestore, а также как использовать ее для создания простого приложения для видеочата.
Чтобы узнать больше, посетите следующие ресурсы: