Envoi de messages poste à poste avec PeerJS

Salutations, chers lecteurs. Dans un article précédent, j'ai expliqué comment créer un simple numéroteur dans un navigateur à l'aide de PeerJS . Et aujourd'hui, je prévois d'examiner comment échanger des messages entre deux utilisateurs directement sans délai.

Qui s'en soucie? Si vous développez un jeu en ligne dans lequel vous avez besoin d'un échange rapide de données entre les joueurs, alors la messagerie directe est peut-être ce dont vous avez besoin.

Balisage et initialisation


Je vais montrer comment la technologie fonctionne, en utilisant un exemple de chat simple entre deux utilisateurs , et je vous dirai également comment adapter le code pour l'échange de données de jeu.

Commençons par le balisage initial et l'initialisation de l'objet homologue

<!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> 

Dans la rubrique nous connectons PeerJS. Quel rôle jouent les éléments avec les indices myid et otherPeerId dans l'article d'appel

Le tableau messList stockera le flux de messages. La fonction addMess ajoutera des éléments à ce tableau et affichera son contenu dans le conteneur de correspondance.

Ensuite, l'initialisation de l'objet homologue, qui est également décrite dans le dernier article .

Maintenant un peu sur les connexions. Pour établir une connexion, il est nécessaire qu'un participant, connaissant le peerID d'un autre, établisse une connexion avec lui et que le second reçoive cette connexion.

Établir une connexion


 peer.on('connection', function(c) { // ... conn=c; initConn(); }); function connectToNode(partnerPeer) { // ... conn = peer.connect(partnerPeer); conn.partnerPeer=partnerPeer; initConn(); } 

L'événement «connexion» pour l'objet homologue se produit sur une connexion entrante. Et la fonction de connexion du pair établit une telle connexion. Dans les deux cas, nous enregistrerons l'objet de connexion dans la variable conn . Étant donné que d'autres actions avec la connexion pour l'exemple d'entraînement actuel seront identiques (bien qu'il puisse y avoir une différence dans le projet de combat), j'ai mis initConn dans une fonction distincte.

 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('----------- -------------');}); } 

Ici, nous suspendons 2 gestionnaires: pour ouvrir et fermer la connexion. Dans le gestionnaire d'ouverture de connexion, nous ajoutons le gestionnaire pour recevoir les données, ce qui ajoutera un message entrant au conteneur de dialogue.

Il ne reste plus qu'à implémenter une fonction qui enverra un message en appuyant sur le bouton Envoyer , ce qui:

  1. ajoute un message à son flux
  2. envoie un message au partenaire (méthode d'envoi de l'objet de connexion)
  3. efface le champ de saisie du message

     function sendMess(elem) { addMess("<div><b>: </b>"+elem.value+"</div>"); conn.send(elem.value); elem.value=""; } 

Adaptation pour transférer des données de jeu


Que faut-il faire pour envoyer de la même manière non pas du texte brut, mais des données qui doivent être échangées pendant les jeux? Rien de vraiment spécial. Dans JS, il existe des méthodes JSON.stringify et JSON.parse qui convertissent un objet en chaîne et vice versa. Enveloppez simplement votre objet de données, convertissez l'objet en une chaîne (JSON.stringify) avant d'envoyer et transformez les données reçues en objet (JSON.parse) une fois reçues

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

En règle générale, de grandes quantités de données ne sont pas nécessaires pour envoyer des objets de jeu et des messages texte. Mais si vous souhaitez transférer le contenu de l'ensemble du conteneur sur la page (un tas de code HTML), gardez à l'esprit qu'une grande connexion peut ne pas atteindre inchangée.

Par expérience personnelle, je dirai: vous ne devez pas transférer des messages de plus de 10 Ko (~ 10 000 caractères) de cette manière. Il vaut mieux écrire un tel message dans un fichier temporaire et envoyer une commande au partenaire pour lire le code de ce fichier (je pense que vous avez compris).

On pourrait s'arrêter là, sinon ...

Rupture de connexion


Oui, cela se produit. La raison en est un Internet instable. Est-il déjà arrivé que vous ayez presque gagné, mais la connexion est rompue et vous perdez tous vos progrès? Pour éviter cela, ajoutons un code qui augmentera la connexion. Nous allons gérer l'événement «fermer» pour cela. Cet événement se produit si:

  1. la connexion a été intentionnellement fermée
  2. la connexion a été perdue en raison d'une mauvaise connexion Internet ou le partenaire a simplement fermé l'onglet

     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('----------- -------------'); }); 

Ici, avec un délai de 2 secondes après la déconnexion, nous essayons simplement d'en établir un nouveau.

Le partenairePeer de l'objet conn n'est présent que dans le partenaire qui a établi la connexion pour la première fois, ce qui signifie qu'un seul des 2 côtés de la connexion commencera à le restaurer lorsqu'il se cassera.

Et maintenant tout le code:

 <!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/fr470189/


All Articles