Firebase + WebRTC Codelab

1. Введение

В этой кодовой лаборатории вы узнаете, как создать простое приложение для видеочата, используя API WebRTC в вашем браузере и Cloud Firestore для передачи сигналов. Приложение называется FirebaseRTC и работает как простой пример, который научит вас основам создания приложений с поддержкой WebRTC.

Что ты узнаешь

  • Выполнение видеозвонка в веб-приложении с помощью WebRTC
  • Передача сигналов удаленной стороне с помощью Cloud Firestore

Что вам понадобится

Перед запуском этой кодовой лаборатории убедитесь, что вы установили:

  • npm, который обычно поставляется с Node.js - рекомендуется Node LTS

2. Создайте и настройте проект Firebase.

Создать проект Firebase

  1. В Firebase консоли , нажмите кнопку Добавить проект, назовите Firebase проекта FirebaseRTC.

Запомните идентификатор проекта для вашего проекта Firebase.

  1. Щелкните Создать проект.

Приложение, которое вы собираетесь создать, использует две службы Firebase, доступные в Интернете:

  • Cloud Firestore для сохранения структурированных данных в облаке и получения мгновенного уведомления при обновлении данных
  • Хостинг Firebase для размещения и обслуживания ваших статических ресурсов

Для этой конкретной кодовой лаборатории вы уже настроили хостинг Firebase в проекте, который будете клонировать. Однако для Cloud Firestore мы проведем вас через настройку и включение служб с помощью консоли Firebase.

Включить Cloud Firestore

Приложение использует Cloud Firestore для сохранения сообщений чата и получения новых сообщений чата.

Вам нужно будет включить Cloud Firestore:

  1. В разделе «Разработка» меню консоли Firebase нажмите «База данных».
  2. Нажмите кнопку Создать базу данных в области облачных Firestore.
  3. Выберите Пуск в опции тестового режима, а затем нажмите кнопку Включить после прочтения заявления об отказе о правилах безопасности.

Тестовый режим гарантирует, что вы можете свободно писать в базу данных во время разработки. Позже в этой лаборатории мы сделаем нашу базу данных более безопасной.

3. Получите образец кода.

Клонируйте репозиторий GitHub из командной строки:

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

Пример кода должен был клонирован в FirebaseRTC каталог. Убедитесь, что с этого момента ваша командная строка запускается из этого каталога:

cd FirebaseRTC

Импортируйте стартовое приложение

Откройте файлы в FirebaseRTC в редакторе и изменить их в соответствии с приведенными ниже инструкциями. Этот каталог содержит начальный код для codelab, который состоит из еще не работающего приложения WebRTC. Мы сделаем его функциональным на протяжении всей этой кодовой лаборатории.

4. Установите интерфейс командной строки Firebase.

Интерфейс командной строки Firebase (CLI) позволяет вам обслуживать ваше веб-приложение локально и развертывать ваше веб-приложение на хостинге Firebase.

  1. Установите CLI, выполнив следующую команду НПМ: 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 как для предложения и ответа, а также два отдельных коллекций с кандидатами 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, а также как использовать это для создания простого приложения для видеочата.

Чтобы узнать больше, посетите следующие ресурсы:

  1. Исходный код FirebaseRTC
  2. Примеры WebRTC
  3. Cloud Firestore