Enviando mensagens ponto a ponto com o PeerJS

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(); // peer var conn; //,   peer.on('open', function(peerID) { document.getElementById('myid').innerHTML=peerID; }); </script> </body> 

No cabeçalho, conectamos o PeerJS. Qual o papel dos elementos com os índices myid e otherPeerId no artigo da chamada

A 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) { // ... conn=c; initConn(); }); function connectToNode(partnerPeer) { // ... conn = peer.connect(partnerPeer); conn.partnerPeer=partnerPeer; initConn(); } 

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 () { //  addMess("<div><h4> </h4></div>"); conn.on ('data', function (data) { //  addMess("<div><b>: </b>"+data+"</div>"); }); }); conn.on('close',function() {addMess('----------- -------------');}); } 

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:

  1. adiciona uma mensagem ao seu feed
  2. envia uma mensagem para o parceiro (método de envio do objeto de conexão)
  3. 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

 // gameObject={x:2,y:5,...} conn.send(JSON.stringify(gameObject)); // conn.on ('data', function (data) { //  gameObject=JSON.parse(data); }); 

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:

  1. a conexão foi intencionalmente fechada
  2. 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> 

Source: https://habr.com/ru/post/pt470189/


All Articles