1. Introdução
Neste codelab, você aprenderá a criar um aplicativo simples de chat por vídeo usando a API WebRTC no seu navegador e o Cloud Firestore para sinalização. O aplicativo é chamado de FirebaseRTC e funciona como um exemplo simples que ensina os conceitos básicos da criação de aplicativos compatíveis com WebRTC.
O que você vai aprender
- Iniciar uma videochamada em um aplicativo da Web usando o WebRTC
- Assinatura para a parte remota usando o Cloud Firestore
Pré-requisitos
Antes de iniciar este codelab, verifique se você instalou:
- npm, que geralmente vem com Node.js: é recomendável usar o Node LTS
2. Criar e configurar um projeto do Firebase
Crie um projeto do Firebase
- No Console do Firebase, clique em "Adicionar projeto" e nomeie o projeto do FirebaseRTRTC.
Lembre-se do ID do projeto do Firebase.
- Clique em "Criar projeto".
O aplicativo que você criará usa dois serviços do Firebase disponíveis na Web:
- Cloud Firestore para salvar dados estruturados na nuvem e receber notificações instantâneas quando os dados são atualizados
- Firebase Hosting para hospedar e exibir seus recursos estáticos
Para este codelab específico, você já configurou o Firebase Hosting no projeto que será clonado. No entanto, para o Cloud Firestore, vamos orientar você sobre a configuração e a ativação dos serviços usando o Console do Firebase.
Ative o Cloud Firestore
O app usa o Cloud Firestore para salvar as mensagens de chat e receber novas mensagens de chat.
Você precisará ativar o Cloud Firestore:
- Na seção "Desenvolver" do Console do Firebase, 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" depois de ler a exoneraçã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. Deixaremos nosso banco de dados mais seguro posteriormente neste codelab.
3. Como conseguir o exemplo de código
Clone o repositório do GitHub na linha de comando:
git clone https://github.com/webrtc/FirebaseRTC
O exemplo de código precisa ter sido clonado para o diretório FirebaseRTC
.
Verifique se a linha de comando está sendo executada nesse diretório a partir de agora:
cd FirebaseRTC
Importar o app inicial
Abra os arquivos em FirebaseRTC
no seu editor e altere-os de acordo com as instruções abaixo. Esse diretório contém o código inicial do
codelab, que consiste em um app WebRTC ainda não funcional. Vamos torná-lo
funcional durante este codelab.
4. Instalar a interface de linha de comando do Firebase
Com a interface de linha de comando (CLI) do Firebase, é possível disponibilizar seu app da Web localmente e implantá-lo 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
Verifique se a versão da CLI do Firebase é a v6.7.1 ou mais recente.
- Autorize a CLI do Firebase executando o seguinte comando:
sh firebase login
Você configurou o modelo de app da Web para extrair a configuração do seu app do Firebase Hosting do diretório local e dos arquivos do seu app. No entanto, para fazer isso, você precisa associar o app ao projeto do Firebase.
Associe o app 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 será útil se você tiver vários ambientes (produção, preparo etc.).
No entanto, para este codelab, vamos usar apenas o alias de default
.
Siga as instruções restantes na linha de comando.
5. Executar o servidor local
Você está pronto para começar a trabalhar no nosso app. Vamos executar o app localmente!
Execute o seguinte comando da CLI do Firebase:
sh firebase serve --only hosting
A linha de comando exibirá a seguinte resposta:
hosting: Local server: http://localhost:5000
Estamos usando o emulador do Firebase Hosting para disponibilizar nosso app localmente. Agora, o app da Web deve estar disponível em http://localhost:5000.
- Abra o aplicativo em http://localhost:5.000.
Você verá sua cópia do FirebaseRTC que foi conectada ao seu projeto do Firebase.
O app se conectou automaticamente ao projeto do Firebase.
6. Criar uma nova sala
Neste app, cada sessão de chat por vídeo é chamada de sala. Um usuário pode criar uma nova sala clicando em um botão no aplicativo. Isso vai gerar um ID que a parte remota pode usar para participar da mesma sala. O ID é usado como chave no Cloud Firestore para cada sala.
Cada sala conterá o RTCSessionDescriptions
da oferta e da
resposta, bem como duas coleções separadas com candidatos ICE de cada parte.
Sua primeira tarefa é implementar o código ausente para criar uma nova sala com
a oferta inicial do autor da chamada. Abra public/app.js
, 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 autor da chamada. Isso é definido como a descrição local e, por fim, escrito
no novo objeto de sala no Cloud Firestore.
Em seguida, detectaremos alterações no banco de dados e detectaremos quando uma resposta do recebedor da chamada for 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 recebedor da chamada grave a RTCSessionDescription
para a
resposta e a defina como a descrição remota no autor da chamada
RTCPeerConnection
.
7. Participar de uma sala
A próxima etapa é implementar a lógica de participar de uma sala. O usuário
faz isso clicando no botão Participar da sala e inserindo o código da sala
para participar. Sua tarefa aqui é implementar a criação de
RTCSessionDescription
para a resposta e atualizar a sala no banco de dados
de acordo com isso.
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 autor da chamada e criando
um RTCSessionDescription
que definimos como a descrição remota. Em seguida, criamos
a resposta, definimos a descrição local e atualizamos o banco de dados. A atualização
do banco de dados acionará o callback onSnapshot
no lado do autor da chamada, que,
por sua vez, definirá a descrição remota com base na resposta do recebedor da chamada.
Isso conclui a troca de objetos RTCSessionDescription
entre o autor da chamada e o recebedor da chamada.
8. Coletar candidatos do ICE
Antes que o autor da chamada e o recebedor da chamada possam se conectar uns aos outros, eles também precisam trocar candidatos ICE que informam ao WebRTC como se conectar ao peering remoto.
A próxima tarefa é implementar o código que detecta 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 detecta candidatos ICE adicionados pelo terminal
remoto e os adiciona à instância RTCPeerConnection
. É importante
detectar mudanças no banco de dados para filtrar qualquer coisa que não seja uma
nova adição, já que de outra forma teríamos adicionado o mesmo conjunto de candidatos ICE
novamente.
9. Conclusão
Neste codelab, você aprendeu a implementar a sinalização para o WebRTC usando o Cloud Firestore e como usá-lo para criar um aplicativo de chat por vídeo simples.
Para saber mais, visite: