إرسال رسائل نظير إلى نظير مع 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. ما هو الدور الذي تلعبه العناصر مع الفهارس myid و otherPeerId في مقال الدعوة

سيتم تخزين مجموعة messList تغذية الرسالة. ستقوم وظيفة addMess بإضافة عناصر إلى هذه المجموعة وإخراج محتوياتها إلى حاوية المراسلات.

التالي هو تهيئة كائن النظير ، والذي تم وصفه أيضًا في المقالة الأخيرة .

الآن قليلا عن الاتصالات. لتأسيس اتصال ، من الضروري أن يقوم أحد المشاركين ، وهو يعرف معرف نظير شخص آخر ، ببدء اتصال معه ، ويتلقى الثاني هذا الاتصال.

تأسيس اتصال


 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 كيلوبايت (حوالي 10،000 حرف) بهذه الطريقة. من الأفضل كتابة مثل هذه الرسالة إلى ملف مؤقت وإرسال أمر إلى الشريك لقراءة الرمز من هذا الملف (أعتقد أنك حصلت على هذه النقطة).

يمكن أن نتوقف عند هذا ، إن لم يكن ...

انقطاع الاتصال


نعم ، هذا يحدث. السبب في ذلك هو الإنترنت غير المستقر. هل حدث أنك ربحت تقريبًا ، ولكن الاتصال مقطوع وتفقد كل تقدمك؟ لتجنب ذلك ، دعنا نضيف رمزًا من شأنه أن يرفع الاتصال الساقط. سوف نتعامل مع الحدث "close" لهذا الغرض. يحدث هذا الحدث إذا:

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

هنا ، مع تأخير لمدة ثانيتين بعد قطع الاتصال ، نحاول ببساطة إنشاء واحدة جديدة.

شريك Partner للكائن conn موجود فقط في الشريك الذي أنشأ الاتصال للمرة الأولى ، مما يعني أن واحدًا فقط من جانبي الاتصال سيبدأ في استعادته عندما ينهار.

والآن الكود كله:

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


All Articles