نصائح مفيدة

Reddwarf لإنشاء خادم Java باستخدام مثال لعبة Rock-Paper-Paper عبر الإنترنت: Server

Pin
Send
Share
Send
Send


اكتب برنامجًا يحاكي لعبة مقص الورق الصخري لشخصين. لتبسيط ، يمكننا أن نفترض أن الحجر - 0 ، مقص - 1 ، ورقة - 2. أو أي ثلاثة أرقام أخرى مناسبة لك. يتم تغذية ولايتين (رقمين) إلى مدخلات البرنامج ؛ في الإخراج ، لدينا حالة الفائز (رقم واحد).
الأمثلة على ذلك:

المدخل: 1 0
الإخراج: 0

المدخل: 0 2
الإخراج: 2

كلما كان الحل أجمل وأقصر ، كان ذلك أفضل.

نهاية عمل القبول: 01/25/15 10:00

الفائز int (int a، int b)
<
عودة القيمة المطلقة (أ - ب) == 1؟ (a> b؟ b: a): (a> b؟ a: b) ،
>

-----------------------------------------------------------------------------------------------------------------
إذا تصورنا أن 0 1 2 عبارة عن أرقام على الخط ، فيمكننا الحديث عن المسافة بينهما. أولاً ، أجد المسافة بينهما ، وإذا كانت 1 ، أي ، فهم يقفون بجانب بعضهم البعض ووفقًا للأولوية ، نختار الحد الأدنى لعدد:
المدخل: 1 0
الإخراج: 0
إذا كانت المسافة تختلف عن 1 ، فهذا يعني أن الرقم ليس قريبًا وتحتاج إلى تحديد الحد الأقصى.
المدخل: 2 0
الإخراج: 2
توفر الوحدة أي ترتيب للأرقام. لقد اعتمدت على حقيقة أن 0 1 2 عبارة عن ثلاثة أرقام مرتبة ، أي أنه يمكن تمثيلها كدائرة يوجد عليها 0 ثم 1 ثم 2 ثم 0 ثم 1 ثم 2 ثم 0 وما إلى ذلك
حسنًا ، عند التعادل ، من الواضح أنه سينجح

إنشاء المشروع

قم بإنشاء مشروع في بيئة التطوير المفضلة لديك.
سيكون المشروع بسيطًا ، لذلك لن نستخدم maven.
للتطوير ، نحتاج إلى مكتبة sgs-server-api-0.10.2.jar من دليل sgs-server-dist-0.10.2 lib

نقوم بإنشاء مجلد META-INF ، يجب أن يحتوي على ملف البيان MANIFEST.MF. بدونها ، يرفض النظام الأساسي العمل مع ملف جرة المشروع. يحتوي ملفي على سطر واحد فقط:
بيان الإصدار: 1.0

أيضًا في مجلد META-INF ، يجب عليك إنشاء ملف app.properties. يحتوي هذا الملف على إعدادات بدء تشغيل الخادم. بالنسبة لمشروعنا ، يحتوي الملف على الخصائص التالية:

هذا هو الحد الأدنى المطلوب من مجموعة الخيارات. أثناء التطوير ، قد لا تزال الخصائص التالية مفيدة:

  • com.sun.sgs.impl.transport.tcp.listen.port - المنفذ الذي يستمع إليه الخادم (الافتراضي 62964)
  • com.sun.sgs.app.authenticators - أسماء الفئات المسؤولة عن المصادقة (تتم إزالة عملية المصادقة من منطق اللعبة ويمكن أن تكون وحدة مستقلة)
  • com.sun.sgs.impl.service.session.allow.new.login - ما إذا كان يجب السماح للاعبين المتصلين من عميل آخر بالاتصال. إذا كان هذا صحيحًا ، فإن الشخص الموجود الآن في اللعبة يلقي. إذا كان خطأ ، لا يسمح بالاتصال من عميل آخر.

اقرأ المزيد عن الخصائص الأخرى في الوثائق.

لعبة العمارة

سوف تتطلب اللعبة الكيانات التالية.
الخادم - فصل يخزن قائمة اللاعبين عبر الإنترنت ويتعامل مع معالجة اتصالهم.
لاعب - يمثل لاعب. اللاعب لديه السمات التالية: الاسم (نفس تسجيل الدخول) وعدد النقاط. قد يشارك في المعركة.
معركة - هي معركة. في هذا الكائن ، في انتظار ردود اللاعبين وتحديد الفائز. أنه يحتوي على روابط لاثنين من اللاعبين.
سلاح - تعداد بسيط للأسلحة: الحجر مباشرة ، مقص والورق.

إذا تم تصويره في شكل رسم تخطيطي للفصل الدراسي ، فسيظهر هذا:

يتم تخزين جميع كيانات اللعبة (باستثناء Weapon) في قاعدة البيانات الداخلية التي توفر المعاملات أثناء تشغيل الخادم ، والرجوع إلى بعضها البعض ، لذلك يجب عليهم تطبيق واجهات java.io.Serializable و com.sun.sgs.app.ManagedObject.

فئة الخادم. تهيئة لاعب والاتصال

فئة الخادم هي نقطة إطلاق الخادم ، لذلك يجب عليها تطبيق واجهة com.sun.sgs.app.AppListener:

يسمى تهيئة باطلة (خصائص الدعائم) في المرة الأولى التي يبدأ فيها الخادم. تملأ قاعدة البيانات الداخلية بالقيم الأولية اللازمة للعمل. ميزة مهمة: إذا تم إيقاف الخادم (أو قتل) وإعادة تشغيله مرة أخرى ، يتم استدعاء هذه الطريقة لنلأن يتم تخزين قاعدة البيانات الداخلية بين بدء تشغيل الخادم وتتيح لك متابعة العمل من اللحظة التي يتوقف فيها.

يسمى ClientSessionListener بتسجيل الدخول (جلسة ClientSession) بعد المصادقة الناجحة ويجب أن يعيد كائنًا يمثل المشغل. في مثالنا ، سيكون هذا اللاعب.

سيتم تخزين جميع اللاعبين المتصلين بالخادم في مجموعة خاصة. Reddwarf لديه مجموعة خاصة من ScalableHashMap للكيانات اللعبة. تتمثل مزايا هذه المجموعة في أنه عند تغييرها ، يتم حظرها (بمعنى أن يتم تأمين قاعدة البيانات الداخلية) ليس كليًا ، ولكن جزئيًا. وفي كائن الخادم ، لن نقوم بتخزين المجموعة نفسها ، ولكن رابطًا لها (ManagedReference).

بالانتقال من الكلمات إلى الأفعال ، نحصل على الكود التالي:

للعمل مع قاعدة البيانات ، يتم استخدام DataManager ، والذي يسمح لك بالكتابة إلى قاعدة البيانات ، والقراءة من قاعدة البيانات وإنشاء روابط ManagedReference. نظرًا لأن قاعدة البيانات عبارة عن وحدة تخزين ذات قيمة مفتاح ، يتم استخدام اسم المشغل ذي البادئة "player". كمفتاح ، ويتم إجراء تسلسل لكائن Player بالكامل إلى القيمة. سنكتب وظيفة لتحميل لاعب من القاعدة (إذا لم يتم العثور على اللاعب في قاعدة البيانات ، قم بإنشائه).

لاعب الطبقة والبروتوكول

جاء الدور لإنشاء فئة المشغل. تمثل هذه الفئة اللاعب وتتلقى إخطارات بالرسائل الواردة من المنصة. لذلك ، حان الوقت للحديث عن البروتوكول. يجعل Reddwarf من الممكن العمل مع الرسائل الواردة والصادرة كصفيف من البايتات ، مما يترك تطبيق البروتوكول وفقًا لتقدير مطور اللعبة. بالنسبة إلى لعبة "مقص الورق الصخري" ، سوف نستخدم بروتوكول نص بسيط.

(الخادم -> العميل) SCORE - يخبر الخادم اللاعب بعدد النقاط
(العميل -> الخادم) PLAY - طلب لاعب لبدء اللعبة
(الخادم -> العميل) BATLE - بدأت المعركة مع اللاعب المحدد
(الخادم -> العميل) خطأ - لم يتم العثور على لاعب المعركة (لا يوجد أحد على الخادم أو في المعركة)
(العميل -> الخادم) ROCK - اللاعب يقول "ستون"
(العميل -> الخادم) SCISSORS - اللاعب يقول "المقص"
(العميل -> الخادم) PAPER - يقول اللاعب "ورقة"
(الخادم -> العميل) إسحب - ارسم
(الخادم -> العميل) WON - فاز اللاعب
(الخادم -> العميل) LOST - لاعب ضائع

من خلال البروتوكول ، يمكنك فهم تسلسل تصرفات اللاعب وقدراته ، لذلك لن نناقش ذلك بشكل منفصل.

يمكنك تشفير النص إلى بايت والعكس بالعكس باستخدام هذا الرمز:

انتقل الآن لكتابة كائن اللاعب.
سيحتفظ اللاعب بالمجالات التالية:

  • الاسم الاول
  • عدد النقاط
  • رابط الخادم (للوصول إلى قائمة اللاعبين عبر الإنترنت)
  • رابط إلى الجلسة (لإرسال رسائل إلى العميل)
  • رابط للمعركة (إذا كان اللاعب الآن في معركة ، وإلا فإنه لاغٍ)

فئات الأسلحة والمعركة

تعداد الأسلحة بسيط للغاية ولا يتطلب أي تعليقات.


نمر إلى المعركة.

تحتوي المعركة على معرف فريد ، وتحتوي على روابط إلى لاعبين ، وإجاباتهم ، بالإضافة إلى علامة نشاط.

بمجرد إنشاء المعركة ، يتم إطلاق مهمة منفصلة ، والتي ستكمل المعركة في 5 ثوان.
بعد هذا الوقت ، يتم تلخيص نتائج المعركة. إذا أعطى واحد فقط من اللاعبين الإجابة ، فسيعتبر الفائز ، إذا كان كلاهما - يتم تحديد الفائز وفقًا للقواعد المعتادة "مقص ورق الصخرة".

يتم تنفيذ المهمة باستخدام خدمة TaskManager ، والتي يمكن الحصول عليها باستخدام AppContext.getTaskManager (). يسمح لك هذا المدير بتشغيل المهام المنفذة في معاملة منفصلة إما على الفور أو بعد فترة زمنية محددة أو بشكل دوري. كما هو متوقع ، يتم تخزين جميع المهام أيضًا في قاعدة البيانات الداخلية ، مما يعني أنه سيتم تنفيذها بعد إعادة تشغيل الخادم.

لذلك ، رمز الفصل هو المعركة.


عند قراءة هذا الرمز ، قد يطرح السؤال التالي: "لماذا تم جعل فئة BattleTimeout الداخلية ثابتة وتخزين رابط المعركة بشكل صريح؟ يمكنك إعلان أنها غير ثابتة والوصول إلى حقول المعركة مباشرةً. "
والحقيقة هي أن الطبقة الداخلية غير الساكنة ستخزن الرابط إلى المعركة الأصلية في شكل ضمني والوصول إلى المعركة من خلالها. لكن ميزات النظام الأساسي Reddwarf (المعاملات) تحظر الوصول إلى ManagedObject (وهو Battle) مباشرةً من معاملة أخرى: في هذه الحالة ، سيتم طرح استثناء ، لأن مرجع مباشر إلى كائن في معاملة أخرى غير صحيح. ترتبط توصية منشئي النظام الأساسي باستخدام الطبقات الداخلية الثابتة فقط بهذا.

أود أيضًا ملاحظة استلام كائن مُدار بواسطة المرجع.
تستخدم التعليمة البرمجية أعلاه لـ ManagedReference أسلوب get () و getForUpdate ().
من حيث المبدأ ، يمكن استخدام فقط الحصول على (). يتيح استخدام getForUpdate () للخادم أن يعرف قبل إتمام المعاملة الكائنات التي سيتم تغييرها ، وإذا تم اكتشاف المعاملات المتعارضة ، لإلغاء المهمة قبل ذلك بقليل. هذا يعطي بعض المكاسب في السرعة مقارنة باستخدام get ().

أخيرًا ، خادمنا جاهز تقريبًا.
أضف القليل من التسجيل (للبساطة نستخدم java.util.logging) ويمكنك بناء المشروع.
نتيجة للتجميع ، يجب أن نحصل على ملف jar ، يقول publish.jar.
إذا كنت لا ترغب في جمع كل هذا يدويًا ، فيمكنك أخذ ملف publish.jar النهائي من هنا.
يجب وضع هذا الملف في sgs-server-dist-0.10.2 dist.
الآن ، في الدليل sgs-server-dist-0.10.2 ، نقوم بتنفيذ الأمر التالي:


نتيجة لذلك ، يمكنك مشاهدة ما يلي في وحدة التحكم:

شاهد الفيديو: Servers vs Desktop PCs as Fast As Possible (شهر اكتوبر 2022).

Pin
Send
Share
Send
Send