使用PeerJS发送对等消息

亲爱的读者,您好! 在上一篇文章中,我讨论了如何使用PeerJS在浏览器中创建简单的拨号程序。 今天,我计划考虑如何在两个用户之间不间断地直接交换消息。

谁在乎? 如果您要开发在线游戏,需要在玩家之间快速交换数据,那么直接消息传递可能就是您所需要的。

标记和初始化


我将以两个用户之间的简单聊天为例,演示该技术的工作原理,并告诉您如何修改代码以交换游戏数据。

让我们从对等对象的初始标记和初始化开始

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

在标题中,我们连接PeerJS。 具有索引myidotherPeerId的元素在通话文章中 扮演什么角色

messList数组将存储消息提要。 addMess函数将元素添加到此数组,并将其内容输出到对应容器。

接下来是对等对象的初始化,在上一篇文章中也有介绍。

现在介绍一下连接。 为了建立连接,有必要让一个参与者知道另一个参与者的peerID,然后开始与他建立连接,而第二个参与者则要接收此连接。

建立连接


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

对等对象的“连接”事件发生在传入连接上。 并与对方连接功能建立这样的连接。 在这两种情况下,我们都将连接对象保存到变量conn中 。 由于针对当前培训示例的连接的进一步操作将是相同的(尽管战斗项目可能有所不同),因此我将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('----------- -------------');}); } 

在这里,我们挂了2个处理程序:打开和关闭连接。 在用于打开连接的处理程序中,我们添加了处理程序以接收数据,这会将传入消息添加到对话框容器。

仅保留实现通过按发送按钮发送消息的功能,该功能:

  1. 向他的供稿中添加一条消息
  2. 向伙伴发送消息(连接对象的发送方法)
  3. 清除消息输入字段

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

适应传输游戏数据


以相同的方式发送不是纯文本,而是在游戏期间需要交换的数据,该怎么办? 没什么特别的。 在JS中,有JSON.stringify和JSON.parse方法将对象转换为字符串,反之亦然。 只需包装您的数据对象,在发送之前将对象转换为字符串(JSON.stringify),并在收到时将接收到的数据转换为对象(JSON.parse)

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

通常,不需要大量数据来发送游戏对象和文本消息。 但是,如果要转发页面上整个容器的内容(一堆HTML代码),请记住,大型连接可能不会保持不变。

根据个人经验,我会说:您不应以这种方式转发超过10 KB(〜10,000个字符)的邮件。 最好将这样的消息写到一个临时文件中,然后发送命令给合作伙伴以从该文件中读取代码(我想您已经明白了)。

如果没有的话,我们可以在此停下来...

连接中断


是的,这正在发生。 原因是互联网不稳定。 是否曾经有过您几乎获胜,但连接中断并且您失去了所有进度的经历吗? 为避免这种情况,让我们添加一个代码,该代码将引发断开的连接。 我们将为此处理“关闭”事件。 如果发生以下情况,就会发生此事件:

  1. 连接被有意关闭
  2. 由于互联网状况不佳而失去了连接,或者合作伙伴只是关闭了标签页

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

在此,断开连接后会有2秒钟的延迟,我们只是在尝试建立一个新的。

conn对象的partnerPeer仅在第一次建立连接的伙伴中存在,这意味着连接断开时,连接的两边中只有一侧会开始恢复连接。

现在整个代码:

 <!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/zh-CN470189/


All Articles