1. Introdução
Neste codelab, você aprenderá a construir um aplicativo de chat de vídeo simples usando a API WebRTC em seu navegador e o Cloud Firestore para sinalização. O aplicativo é denominado FirebaseRTC e funciona como um exemplo simples que lhe ensinará os fundamentos da construção de aplicativos habilitados para WebRTC.
O que você aprenderá
- Iniciar uma videochamada em um aplicativo da web usando WebRTC
- Sinalizar para a parte remota usando o Cloud Firestore
O que você precisará
Antes de iniciar este codelab, verifique se você instalou:
- npm que normalmente vem com Node.js - Node LTS é recomendado
2. Crie e configure um projeto Firebase
Crie um projeto Firebase
- No Firebase console , clique em Adicionar projeto e nomeie o projeto Firebase como FirebaseRTC.
Lembre-se do ID do projeto para seu projeto Firebase.
- Clique em Criar projeto.
O aplicativo que você vai construir usa dois serviços Firebase disponíveis na web:
- Cloud Firestore para salvar dados estruturados na nuvem e receber notificação instantânea quando os dados forem atualizados
- Firebase Hosting para hospedar e servir seus ativos estáticos
Para este codelab específico, você já configurou o Firebase Hosting no projeto que clonará. No entanto, para o Cloud Firestore, orientaremos você na configuração e ativação dos serviços usando o console do Firebase.
Ativar Cloud Firestore
O aplicativo usa o Cloud Firestore para salvar as mensagens de bate-papo e receber novas mensagens de bate-papo.
Você precisará ativar o Cloud Firestore:
- Na seção Desenvolver do menu do Firebase console, clique em Banco de dados.
- Clique em Criar banco de dados no painel do Cloud Firestore.
- Selecione a opção Iniciar no modo de teste e clique em Ativar após ler o aviso de isenção de responsabilidade sobre as regras de segurança.
O modo de teste garante que você possa gravar livremente no banco de dados durante o desenvolvimento. Tornaremos nosso banco de dados mais seguro posteriormente neste codelab.
3. Obtenha o código de amostra
Clone o repositório GitHub a partir da linha de comando:
git clone https://github.com/webrtc/FirebaseRTC
O código de amostra deve ter sido clonado no diretório FirebaseRTC
. Certifique-se de que sua linha de comando seja executada a partir deste diretório a partir de agora:
cd FirebaseRTC
Importe o aplicativo inicial
Abra os arquivos no FirebaseRTC
em seu editor e altere-os de acordo com as instruções abaixo. Este diretório contém o código inicial para o codelab que consiste em um aplicativo WebRTC ainda não funcional. Vamos torná-lo funcional em todo este codelab.
4. Instale a interface de linha de comando do Firebase
A Firebase Command Line Interface (CLI) permite que você veicule seu aplicativo da web localmente e implante-o no Firebase Hosting.
- Instale a CLI executando o seguinte comando npm:
sh npm -g install firebase-tools
- Verifique se a CLI foi instalada corretamente executando o seguinte comando:
sh firebase --version
Certifique-se de que a versão da Firebase CLI é v6.7.1 ou posterior.
- Autorize a Firebase CLI executando o seguinte comando:
sh firebase login
Você configurou o modelo de aplicativo da web para obter a configuração do seu aplicativo para Firebase Hosting do diretório local e dos arquivos do seu aplicativo. Mas, para fazer isso, você precisa associar seu aplicativo ao projeto Firebase.
Associe seu aplicativo ao projeto do Firebase executando o seguinte comando:
sh firebase use --add
Quando solicitado, selecione o ID do projeto e atribua um alias ao projeto do Firebase.
Um alias é útil se você tiver vários ambientes (produção, teste, etc). No entanto, para este codelab, vamos apenas usar o alias de default
.
Siga as instruções restantes em sua linha de comando.
5. Execute o servidor local
Você está pronto para realmente começar a trabalhar em nosso aplicativo! Vamos executar o aplicativo localmente!
Execute o seguinte comando da Firebase CLI:
sh firebase serve --only hosting
Sua linha de comando deve exibir a seguinte resposta:
hosting: Local server: http://localhost:5000
Estamos usando o emulador do Firebase Hosting para servir nosso aplicativo localmente. O aplicativo da web agora deve estar disponível em http: // localhost: 5000.
- Abra seu aplicativo em http: // localhost: 5000.
Você deve ver sua cópia do FirebaseRTC que foi conectada ao seu projeto do Firebase.
O aplicativo foi conectado automaticamente ao seu projeto Firebase.
6. Criação de uma nova sala
Neste aplicativo, cada sessão de chat de vídeo é chamada de sala. Um usuário pode criar uma nova sala clicando em um botão em seu aplicativo. Isso irá gerar um ID que o ponto remoto pode usar para entrar na mesma sala. O ID é usado como chave no Cloud Firestore para cada quarto.
Cada sala conterá as RTCSessionDescriptions
para a oferta e a resposta, bem como duas coleções separadas com candidatos ICE de cada partido.
Sua primeira tarefa é implementar o código que falta para criar uma nova sala com a oferta inicial do chamador. Abra public/app.js
e encontre o comentário // Add code for creating a room here
e adicione o seguinte código:
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!`
A primeira linha cria um RTCSessionDescription
que representará a oferta do chamador. Em seguida, é definido como a descrição local e, finalmente, gravado no novo objeto de sala no Cloud Firestore.
A seguir, ouviremos as alterações no banco de dados e detectaremos quando uma resposta do receptor foi adicionada.
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);
}
});
Isso aguardará até que o receptor escreva RTCSessionDescription
para a resposta e defina-o como a descrição remota no chamador RTCPeerConnection
.
7. Entrando em uma sala
A próxima etapa é implementar a lógica para ingressar em uma sala existente. O usuário faz isso clicando no botão Entrar na sala e inserindo o ID da sala a ser ingressada. Sua tarefa aqui é implementar a criação de RTCSessionDescription
para a resposta e atualizar a sala no banco de dados de acordo.
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);
No código acima, começamos extraindo a oferta do chamador e criando um RTCSessionDescription
que definimos como a descrição remota. Em seguida, criamos a resposta, definimos como a descrição local e atualizamos o banco de dados. A atualização do banco de dados acionará o retorno de chamada onSnapshot
no lado do chamador, que por sua vez definirá a descrição remota com base na resposta do receptor. Isso conclui a troca dos objetos RTCSessionDescription
entre o chamador e o receptor.
8. Colete candidatos ICE
Antes que o chamador e o receptor possam se conectar, eles também precisam trocar candidatos ICE que dizem ao WebRTC como se conectar ao par remoto. Sua próxima tarefa é implementar o código que escuta os candidatos ICE e os adiciona a uma coleção no banco de dados. Encontre a função collectIceCandidates
e adicione o seguinte código:
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);
}
});
})
}
Essa função faz duas coisas. Ele coleta candidatos ICE da API WebRTC e os adiciona ao banco de dados, e ouve candidatos ICE adicionados do par remoto e os adiciona à sua instância RTCPeerConnection
. É importante, ao ouvir as alterações do banco de dados, filtrar qualquer coisa que não seja uma nova adição, uma vez que, de outra forma, teríamos adicionado o mesmo conjunto de candidatos ICE repetidamente.
9. Conclusão
Neste codelab, você aprendeu como implementar a sinalização para WebRTC usando o Cloud Firestore, bem como como usá-la para criar um aplicativo de chat de vídeo simples.
Para saber mais, visite os seguintes recursos: