Senden von Peer-to-Peer-Nachrichten mit PeerJS

Grüße, liebe Leser. In einem früheren Artikel habe ich darüber gesprochen, wie man mit PeerJS einen einfachen Dialer in einem Browser erstellt . Und heute habe ich vor zu überlegen, wie Nachrichten ohne Verzögerung direkt zwischen zwei Benutzern ausgetauscht werden können.

Wen interessiert das? Wenn Sie ein Online-Spiel entwickeln, in dem Sie einen schnellen Datenaustausch zwischen Spielern benötigen, ist Direct Messaging möglicherweise das Richtige für Sie.

Markup und Initialisierung


Ich werde anhand eines Beispiels eines einfachen Chats zwischen zwei Benutzern zeigen, wie die Technologie funktioniert, und Ihnen zeigen, wie Sie den Code für den Austausch von Spieldaten anpassen können.

Beginnen wir mit dem anfänglichen Markup und der Initialisierung des Peer-Objekts

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

In der Überschrift verbinden wir PeerJS. Welche Rolle spielen Elemente mit den Indizes myid und otherPeerId im Aufrufartikel ?

Das messList- Array speichert den Nachrichtenfeed. Die Funktion addMess fügt diesem Array Elemente hinzu und gibt seinen Inhalt an den Korrespondenzcontainer aus.

Als nächstes folgt die Initialisierung des Peer-Objekts, die auch im letzten Artikel beschrieben wird .

Nun ein wenig über Verbindungen. Um eine Verbindung herzustellen, muss ein Teilnehmer, der die Peer-ID eines anderen kennt, eine Verbindung mit ihm herstellen, und der zweite erhält diese Verbindung.

Stellen Sie eine Verbindung her


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

Das 'Verbindungs'-Ereignis für das Peer- Objekt tritt bei einer eingehenden Verbindung auf. Und die Verbindungsfunktion des Peer- Objekts stellt eine solche Verbindung her. In beiden Fällen speichern wir das Verbindungsobjekt in der Variablen conn . Da weitere Aktionen mit der Verbindung für das aktuelle Trainingsbeispiel identisch sind (obwohl es im Kampfprojekt einen Unterschied geben kann), habe ich initConn in eine separate Funktion gestellt.

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

Hier hängen wir 2 Handler: zum Öffnen und Schließen der Verbindung. Im Handler zum Öffnen einer Verbindung fügen wir den Handler zum Empfangen von Daten hinzu, wodurch dem Dialogcontainer eine eingehende Nachricht hinzugefügt wird.

Es bleibt nur eine Funktion zu implementieren, die eine Nachricht durch Drücken der Schaltfläche Senden sendet.

  1. fügt seinem Feed eine Nachricht hinzu
  2. sendet eine Nachricht an den Partner (Sendemethode des Verbindungsobjekts)
  3. löscht das Nachrichteneingabefeld

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

Anpassung an die Übertragung von Spieldaten


Was muss getan werden, um auf die gleiche Weise keinen einfachen Text zu senden, sondern Daten, die während der Spiele ausgetauscht werden müssen? Nichts wirklich Besonderes. In JS gibt es die Methoden JSON.stringify und JSON.parse, die ein Objekt in eine Zeichenfolge konvertieren und umgekehrt. Wickeln Sie einfach Ihr Datenobjekt ein, konvertieren Sie das Objekt vor dem Senden in eine Zeichenfolge (JSON.stringify) und verwandeln Sie die empfangenen Daten beim Empfang in ein Objekt (JSON.parse)

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

In der Regel werden keine großen Datenmengen zum Senden von Spielobjekten und Textnachrichten benötigt. Wenn Sie jedoch den Inhalt des gesamten Containers auf der Seite (eine Menge HTML-Code) weiterleiten möchten, beachten Sie, dass eine große Verbindung möglicherweise nicht unverändert bleibt.

Aus persönlicher Erfahrung möchte ich sagen: Sie sollten auf diese Weise keine Nachrichten mit mehr als 10 KB (~ 10.000 Zeichen) weiterleiten. Es ist besser, eine solche Nachricht in eine temporäre Datei zu schreiben und einen Befehl an den Partner zu senden, um den Code aus dieser Datei zu lesen (ich denke, Sie haben den Punkt verstanden).

Wir könnten damit aufhören, wenn nicht ...

Verbindungsunterbrechung


Ja, das passiert gerade. Der Grund dafür ist das instabile Internet. Ist es jemals passiert, dass Sie fast gewonnen haben, aber die Verbindung unterbrochen ist und Sie alle Ihre Fortschritte verlieren? Um dies zu vermeiden, fügen wir einen Code hinzu, der eine unterbrochene Verbindung auslöst. Wir werden das Ereignis "schließen" dafür behandeln. Dieses Ereignis tritt auf, wenn:

  1. Die Verbindung wurde absichtlich geschlossen
  2. Die Verbindung wurde aufgrund eines schlechten Internets unterbrochen oder der Partner schloss einfach den Tab

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

Hier versuchen wir mit einer Verzögerung von 2 Sekunden nach dem Trennen einfach, eine neue einzurichten.

Der partnerPeer des conn-Objekts ist nur in dem Partner vorhanden, der die Verbindung zum ersten Mal hergestellt hat. Dies bedeutet, dass nur eine der beiden Seiten der Verbindung beginnt, sie wiederherzustellen, wenn sie unterbrochen wird.

Und jetzt der ganze 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/de470189/


All Articles