🔒🗝️Simples chat de ponta a ponta com PeerJS - REACT🗝️🔒
Comunicação ponto a ponto simplificada com PeerJS
Biblioteca JavaScript que atua como um wrapper em torno do WebRTC
Implementar a comunicação peer-to-peer é uma tarefa desafiadora. Mas, se você conhece as ferramentas corretas, pode tornar isso muito mais fácil.
Portanto, neste artigo, discutirei o PeerJS , uma biblioteca JavaScript que atua como um wrapper em torno do WebRTC, facilitando a implementação da comunicação ponto a ponto em aplicativos da web.
Como o PeerJS simplifica o WebRTC?
Quando se trata de comunicação P2P em tempo real em aplicativos da Web, o WebRTC é o padrão usado por muitos desenvolvedores. Mas, vem com algumas complexidades como segue;
- Se você usar WebRTC puro, primeiro defina um servidor STUN (Session Traversal Utilities for NAT) para gerar candidatos ICE (Interactive Connectivity Establishment) para cada par envolvido na comunicação.
- Então você precisa usar seus servidores para armazenar esses detalhes do candidato ICE.
- Por fim, você precisa implementar WebSockets para lidar com atualizações em tempo real. Mesmo que você nunca tenha trabalhado com WebRTC antes; Tenho certeza que você deve estar sentindo a complexidade de sua implementação. Mas não se preocupe, o PeerJS está aqui para resgatá-lo.
Com o PeerJS, não precisamos nos preocupar com STUNs, candidatos a ICE ou criação de servidores. Podemos até evitar a implementação de WebSockets também.
PeerJs fornece uma API de conexão peer-to-peer completa e configurável e um servidor chamado PeerServer para estabelecer facilmente conexões entre clientes PeerJS.
Então, vamos ver como podemos usar o PeerJS para criar um aplicativo de chat simples.
Construindo sua primeira sala de bate-papo com PeerJS e React
Passo 1 — Instalando o PeerJS
Primeiro, precisamos instalar a biblioteca PeerJS em seu projeto como um módulo de nó e a biblioteca de pares como uma dependência global.
// Instalando PeerJS
npm i peerjs
// Instalando Peer
npm i -g peer
Passo 2 — Implementando a Sala de Chat
Agora, vamos passar para nosso aplicativo React e iniciar as coisas inicializando o estado do componente de bate-papo.
Dentro do estado, estaremos lidando com nosso ID, ID do par, mensagens de bate-papo e uma instância do objeto Peer.
state = {
myId: '',
friendId: '',
par: {},
mensagem: '',
mensagens: []
}
Em seguida, precisamos criar uma instância Peer definindo o nome do host, a porta e o caminho para gerenciar nossa conexão P2P. Usaremos essa instância durante todo o processo de comunicação.
const peer = new Peer('', {
host: 'localhost',
porta: '3001',
caminho: '/'
});
Dica: Você pode usar seu próprio ID como primeiro argumento ou deixá-lo indefinido para o PeerServer gerar um ID aleatório. Se você usar const peer = new Peer();, estará conectado ao PeerServer Cloud.
A instância de par tem vários métodos para lidar com a comunicação entre pares. peer.oné usado para ouvir eventos de peer e é útil ao receber chamadas de peers remotos.
openO evento será emitido após a conexão bem-sucedida ao PeerServer e usaremos esse evento para atualizar o estado do myId e da instância do mesmo nível.
peer.on('abrir', (id) => {
this.setState({
myId: id,
peer: peer
});
});
Em seguida, precisamos usar o connectionevento para ouvir as conexões de ponto remoto e podemos usar seu callback para capturar a mensagem enviada pelo ponto remoto.
peer.on('conexão', (conn) => {
conn.on('dados', (dados) => {
this.setState({
mensagens: [...this.state.mensagens, dados]
});
});
});
Agora, implementamos todas as funcionalidades para receber mensagens. Como etapa final, vamos criar um método para enviar uma mensagem.
peer.connectO método nos permite conectar ao par especificando o id do par. Em seguida, ele retorna um DataConnectionobjeto que pode ser usado para enviar dados de mensagem para o par.
enviar = () => {
const conn = this.state.peer.connect(this.state.friendId);
conn.on('abrir', () => {
const msgObj = {
remetente: this.state.myId,
mensagem: this.state.message
};
conn.send(msgObj);
this.setState({
mensagens: [...this.state.messages, msgObj],
mensagem: ''
});
});
}
Etapa 3 — Implementação do bate-papo por vídeo
Agora, vamos modificar nossa sala de chat para enviar mensagens de vídeo. A implementação é muito semelhante ao que discutimos na etapa anterior. Podemos usar o método calldentro do evento peer.onpara ouvir as chamadas do ponto remoto. Ele fornecerá um retorno de chamada com um objeto nomeado MediaConnectione os fluxos de vídeo e áudio do receptor serão fornecidos ao answermétodo do MediaConnectionobjeto.
peer.on('chamar', (chamar) => {
var getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
getUserMedia({ video: true, audio: true }, (stream) => {
this.myVideo.srcObject = fluxo;
this.myVideo.play();
call.answer(fluxo);
call.on('stream', (remoteStream) => {
this.friendVideo.srcObject = remoteStream;
this.friendVideo.play();
});
}, erro => { console.log('Erro!') });
});
Agora vamos fazer uma chamada de vídeo para o par do nosso lado. Essa abordagem é semelhante a atender uma chamada. Precisamos usar o callmétodo da peerinstância inicial e fornecer ID de par e fluxo de vídeo como argumentos.
callO método retornará um MediaConnectionobjeto que podemos usar para acessar o fluxo do par.
videochamada = () => {
var getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
getUserMedia({ video: true, audio: true }, (stream) => {
this.myVideo.srcObject = fluxo;
this.myVideo.play();
const call = this.state.peer.call(this.state.friendId, stream);
call.on('stream', (remoteStream) => {
this.friendVideo.srcObject = remoteStream;
this.friendVideo.play();
});
}, erro => { console.log('Erro!') });
}
Passo 4 — Finalizando as Coisas
Finalmente, é hora de adicionar um pouco de JSX para renderizar nossa sala de bate-papo. Vamos adicionar dois campos de entrada para ID de par e mensagens de bate-papo. Usaremos o refatributo para acessar o videoelemento.
return (
<div className="wrapper">
<div className="col">
<h1>Meu ID: {this.state.myId}</h1>
<label>ID do amigo:</label>
<input
type="text"
value={this.state.friendId}
onChange={e => { this.setState({ friendId: e.target.value });}} />
<br />
<br />
<label>Mensagem:</label>
<input
type="text"
value={this.state.message}
onChange={e => { this.setState({ message: e.target.value }); }} />
<button onClick={this.send}>Enviar</button>
<button onClick={this.videoCall}>Chamada de vídeo</button>
{
this.state.messages.map((message, i) => {
return (
<div key={i}>
<h3>{message.sender}:</h3>
<p>{message.message}</p>
</div>
)
});
}
</div>
<div className="col">
<div>
<video ref={ref => this.myVideo = ref} />
</div>
<div>
<video ref={ref => this.friendVideo = ref} />
</div>
<
É isso! Agora estamos prontos para um rápido bate-papo por vídeo. A implementação final ficará assim e você pode encontrar o código completo no meu repositório GitHub .
Observação: alguns navegadores (especialmente navegadores móveis) podem não permitir o acesso à câmera e ao microfone sem uma conexão HTTPS. Você pode consultar este artigo para configurar uma conexão HTTPS local em algumas etapas.
Construa com componentes independentes, para velocidade e escala
Em vez de criar aplicativos monolíticos, crie primeiro componentes independentes e componha-os em recursos e aplicativos. Ele torna o desenvolvimento mais rápido e ajuda as equipes a criar aplicativos mais consistentes e escaláveis.
Ferramentas OSS como o Bit oferecem uma ótima experiência de desenvolvedor para criar componentes independentes e compor aplicativos. Muitos times começam construindo seus Design Systems ou Micro Frontends, através de componentes independentes. Experimente
Palavras Finais
Web RTC é o padrão de navegador que permite a comunicação ponto a ponto em tempo real. Mas a implementação do WebRTC é um pouco complexa devido ao envolvimento de servidores STUN, candidatos a ICE, SDPs e WebSockets.
PeerJS simplifica todo o processo atuando como um wrapper para WebRTC e nos fornece eventos e métodos muito mais simples de trabalhar.
Então, convido você a experimentar o PeerJS e deixe-me saber sua opinião na seção de comentários.
Este artigo foi traduzido para afins de repasse de conhecimento, agradecimentos: https://blog.bitsrc.io/simplified-peer-to-peer-communication-with-peerjs-e37244267723