Saudações, queridos leitores. Em um
artigo anterior, falei sobre como criar um discador simples em um navegador usando o
PeerJS . E hoje pretendo considerar como trocar mensagens entre dois usuários diretamente, sem demora.
Quem se importa? Se você está desenvolvendo um jogo on-line no qual precisa de uma troca rápida de dados entre os jogadores, talvez seja necessário o uso de mensagens diretas.
Marcação e inicialização
Mostrarei como a tecnologia funciona, usando um exemplo de um
bate-papo simples
entre dois usuários , e também mostrarei como adaptar o código para a troca de dados do jogo.
Vamos começar com a marcação inicial e a inicialização do objeto de mesmo nível
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>PeerJS </title> <script src="https://unpkg.com/peerjs@1.0.0/dist/peerjs.min.js"></script> </head> <body> <h3> ID: <span id=myid ></span></h3> <input id=otherPeerId type=text placeholder="otherPeerId" ><button onclick="connectToNode(document.getElementById('otherPeerId').value)"></button> <div id=messages style="width:400px;height:60vh; background:#ADD8E6;margin:5px;"> </div><br> <textarea id=mess style="width:400px;height:15vh" ></textarea><br> <button onclick="sendMess(document.getElementById('mess'))"></button> <script> var messList=[]; function addMess(mess) { messList.push(mess); document.getElementById('messages').innerHTML=messList.join(""); } var peer=new Peer(); </script> </body>
No cabeçalho, conectamos o PeerJS. Qual o papel dos elementos com os índices
myid e
otherPeerId no
artigo da chamadaA matriz
messList armazenará o feed de mensagens. A função
addMess adicionará elementos a essa matriz e
enviará seu conteúdo para o contêiner de correspondência.
A seguir, é apresentada a inicialização do objeto de mesmo nível, descrito também no
último artigo .
Agora um pouco sobre conexões. Para estabelecer uma conexão, é necessário que um participante, conhecendo o peerID de outro, inicie uma conexão com ele e o segundo receba essa conexão.
Estabelecer uma conexão
peer.on('connection', function(c) {
O evento 'conexão' para o objeto de mesmo nível ocorre em uma conexão de entrada. E a função de
conexão do
par estabelece essa conexão. Nos dois casos, salvaremos o objeto de
conexão na variável
conn . Como outras ações com a conexão para o exemplo de treinamento atual serão idênticas (embora possa haver uma diferença no projeto de combate), coloquei o initConn em uma função separada.
function initConn() { conn.on ('open', function () {
Aqui nós penduramos 2 manipuladores: para abrir e fechar a conexão. No manipulador para abrir uma conexão, adicionamos o manipulador para receber dados, o que adicionará uma mensagem recebida ao contêiner de diálogo.
Resta apenas implementar uma função que enviará uma mensagem pressionando o botão
Enviar , que:
- adiciona uma mensagem ao seu feed
- envia uma mensagem para o parceiro (método de envio do objeto de conexão)
- limpa o campo de entrada da mensagem
function sendMess(elem) { addMess("<div><b>: </b>"+elem.value+"</div>"); conn.send(elem.value); elem.value=""; }
Adaptação para transferir dados do jogo
O que precisa ser feito para enviar da mesma maneira não texto simples, mas dados que precisam ser trocados durante os jogos? Nada realmente especial. No JS, existem os métodos JSON.stringify e JSON.parse que convertem um objeto em uma string e vice-versa. Apenas envolva seu objeto de dados, converta o objeto em uma string (JSON.stringify) antes de enviar e transforme os dados recebidos em um objeto (JSON.parse) quando recebido
Normalmente, grandes quantidades de dados não são necessárias para enviar objetos de jogo e mensagens de texto. Mas se você deseja encaminhar o conteúdo de todo o contêiner na página (um monte de código HTML), lembre-se de que uma conexão grande pode não atingir inalterada.
Por experiência pessoal, direi: você não deve encaminhar mensagens com mais de 10 KB (~ 10.000 caracteres) dessa maneira. É melhor escrever essa mensagem em um arquivo temporário e enviar um comando ao parceiro para ler o código desse arquivo (acho que você entendeu).
Poderíamos parar com isso, se não ...
Quebra de conexão
Sim, isso está acontecendo. A razão para isso é a Internet instável. Já aconteceu que você quase venceu, mas a conexão está quebrada e você perde todo o seu progresso? Para evitar isso, vamos adicionar um código que gerará uma conexão caída. Lidaremos com o evento 'close' para isso. Este evento ocorre se:
- a conexão foi intencionalmente fechada
- a conexão foi perdida devido à falta de internet ou o parceiro simplesmente fechou a guia
conn.on('close',function() { setTimeout(function() { if(conn.partnerPeer) { var pp=conn.partnerPeer; conn = peer.connect(conn.partnerPeer); conn.partnerPeer=pp; initConn(); } else conn=null; } ,2000); addMess('----------- -------------'); });
Aqui, com um atraso de 2 segundos após a desconexão, estamos simplesmente tentando estabelecer um novo.
O partnerPeer do objeto conn está presente apenas no parceiro que estabeleceu a conexão pela primeira vez, o que significa que apenas um dos dois lados da conexão começará a restaurá-lo quando ele quebrar.
E agora todo o código:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>PeerJS </title> <script src="https://unpkg.com/peerjs@1.0.0/dist/peerjs.min.js"></script> </head> <body> <h3> ID: <span id=myid ></span></h3> <input id=otherPeerId type=text placeholder="otherPeerId" ><button onclick="connectToNode(document.getElementById('otherPeerId').value)"></button> <div id=messages style="width:400px;height:60vh; background:#ADD8E6;margin:5px;"> </div><br> <textarea id=mess style="width:400px;height:15vh" ></textarea><br> <button onclick="sendMess(document.getElementById('mess'))"></button> <script> var messList=[]; function addMess(mess) { messList.push(mess); document.getElementById('messages').innerHTML=messList.join(""); } var peer=new Peer(); var conn; //, peer.on('open', function(peerID) { document.getElementById('myid').innerHTML=peerID; }); peer.on('connection', function(c) { // ... conn=c; initConn(); }); function connectToNode(partnerPeer) { // ... conn = peer.connect(partnerPeer); initConn(); } function initConn() { conn.on ('open', function () { // addMess("<div><h4> </h4></div>"); conn.on ('data', function (data) { // addMess("<div><b>: </b>"+data+"</div>"); }); }); conn.on('close',function() {addMess('----------- -------------');}); } function sendMess(elem) { addMess("<div><b>: </b>"+elem.value+"</div>"); conn.send(elem.value); elem.value=""; } </script> </body>