Greetings, dear readers. In a
previous article, I talked about how to make a simple dialer in a browser using
PeerJS . And today I plan to consider how to exchange messages between two users directly without delay.
Who cares? If you are developing an online game in which you need a quick exchange of data between players, then direct messaging is perhaps what you need.
Markup and initialization
I will show how the technology works, using an example of a simple
chat between two users , and also tell you how to adapt the code for exchanging game data.
Let's start with the initial markup and initialization of the peer object
<!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>
In the heading we connect PeerJS. What role do the elements with
myid and
otherPeerId indices
play in
the call article
The
messList array will store the message feed. The
addMess function will add elements to this array and output its contents to the correspondence container.
Next up is the initialization of the peer object, which is also described in the
last article .
Now a little about connections. To establish a connection, it is necessary that one participant, knowing the peerID of another, start a connection with him, and the second one receives this connection.
Establish a connection
peer.on('connection', function(c) {
The 'connection' event for the
peer object occurs on an incoming connection. And the
connect function of the
peer object establishes such a connection. In both cases, we will save the
connection object to the variable
conn . Since further actions with the connection for the current training example will be identical (although there may be a difference in the combat project), I put initConn into a separate function.
function initConn() { conn.on ('open', function () {
Here we hang 2 handlers: to open and to close the connection. In the handler for opening a connection, we add the handler to receive data, which will add an incoming message to the dialog container.
It remains only to implement a function that will send a message by pressing the
Send button, which:
- adds a message to his feed
- sends a message to the partner (send method of the connection object)
- clears the message entry field
function sendMess(elem) { addMess("<div><b>: </b>"+elem.value+"</div>"); conn.send(elem.value); elem.value=""; }
Adaptation to transfer game data
What needs to be done in order to send in the same way not ordinary text, but data that needs to be exchanged during games? Nothing really special. In JS, there are JSON.stringify and JSON.parse methods that convert an object to a string and vice versa. Just wrap your data object, convert the object to a string (JSON.stringify) before sending and turn the received data into an object (JSON.parse) when received
Typically, large amounts of data are not needed to send game objects and text messages. But if you are going to forward the contents of the entire container on the page (a bunch of HTML code), keep in mind that a large connection may not reach unchanged.
From personal experience I’ll say: you should not forward messages more than 10 KB (~ 10 000 characters) in this way. It is better to write such a message to a temporary file and send a command to the partner to read the code from this file (I think you got the point).
We could stop at this, if not ...
Connection break
Yes, this is happening. The reason for this is unstable Internet. Has it ever happened that you have almost won, but the connection is broken and you lose all your progress? To avoid this, let's add a code that will raise a fallen connection. We will handle the event 'close' for this. This event occurs if:
- the connection was intentionally closed
- connection was lost due to poor internet or the partner simply closed the 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('----------- -------------'); });
Here we, with a delay of 2 seconds after a disconnection, are simply trying to establish a new one.
The partnerPeer of the conn object is present only in the partner who established the connection for the first time, which means that only one of the 2 sides of the connection will start to restore it when it breaks.
And now the whole 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>