لنفترض أنه لدينا تطبيق للتصويت في موقعنا يستطيع بواسطته الزوار إبداء آرائهم في مسألة معينة، مثلا عن لغة البرمجة المفضلة لديهم، التطبيق طبعا سيكون عبارة عن لائحة من الإختيارات ويستطيع الزائر الإختيار ثم الضغط على زر الإرسال من أجل حفظ اختياره في قاعدة البيانات.
بدون الأجاكس
بدون الأجاكس سيظطر الزائر للضغط على زر الإرسال وإرسال طلب HTTP للخادم من أجل الحفظ في قاعدة البيانات وبعد ذلك يتم إعادة تحميل الصفحة كليا من أجل التحديث، وهذا كان عبئا كبيرا على الخوادم وعلى المتصفحات قبل ظهور تقنية الأجاكس بحيث نجبر الخادم على إعادة إرسال جميع عناصر الصفحة إلى المتصفح رغم أننا لم نم بتحديث سوى منطقة التصويت، أي أننا أجبرناه على القيام بأعمال لسنا بحاجة إليها.
مع الأجاكس
لحسن الحظ مع لم يعد هذا المشكل مطروحا بعد ظهور تقنية الأجاكس التي لاقت نجاحا منقطع النظير وارتقت مع تطبيقات الويب إلى مستويات أعلى بكثير عما سبق، فباستعمال الأجاكس نستطيع إرسال طلب HTTP للخادم عن طريق الجافاسكريبت بواسطة الكائن XMLHttpRequest وبدوره يرسل(الخادم) الإجابة إلى نفس الكائن وتكون عادة عبارة عن نصوص، أو بيانات JSON أو XML من دون الحاجة لإعادة تحميل الصفحة فيقوم بواسطتها المبرمج بتحديث ما يريده فقط أو ما يهم الزائر فقط. وهذه خطوة كبيرة نحو الأمام في سبيل تحسين أداء والحفاظ على موارد الخوادم.
لكن ؟!
لكن ماذا لو أردنا مثلا أن نرى نتيجة التصويت بعد 10 أو 20 دقيقة من تصويتنا، سنضطر بالطبع لإعادة تحميل الصفحة لكي نسأل الخادم عن جديد التصويت، فالأخير لا يستطيع إرسال إشعار للمستعمل عند حدث معين من التوصل بطلب منه وهذا هو الحد الذي وصل إليه ال HTTP. فعندما نريد تحميل صفحة معينة نقوم بإرسال طلبية للخادم فيتم فيه فتح منفذ (Port/Socket) يتم عبره إرسال الجواب وبعد ذلك يتم إغلاقه وإيقاف الإتصال بين الخادم والمتصفح حتى يتوصل بطلبية أخرى وتتكرر نفس العملية.
فلنفترض مثلا أن هناك 100 زائر على الموقع في نفس الوقت ونعتبر مجازا أن كل زائر هو جندي والخادم هو الجنرال، تخيلوا معي معاناة هذا الجنرال عندما يسأله كل زائر إن كانت هنالك أوامر جديدة حيث سيظطر في حالة عدم وجودها لقول كلمة “لا” لكل جندي على حدة أي أنه سيكررها 100 مرة ولم يكن من داعي لقولها أصلا مادامت لم تكن هنالك أوامر أصلا.
الحل مع “الويب سوكتس” WebSockets
لنعتبر أن WebSockets هي عبارة عن قناة يتم فتحها بين الخادم والمستعمل وتظل مفتوحة ويبقى الإتصال قائما طوال مدة فتح التطبيق وهي ثنائية الإتجاه (Bidirectional) أي أنها تمكن المستعمل من إرسال طلبيات للخادم والعكس صحيح أي أنه أصبح باستطاعة الخادم استخدام بروتوكولات WebSockets من أجل الإتصال بالمستعمل عند حدث معين من دون أن يظل جامدا في مكانه ينتظر تلقي الطلبات.
وهكذا باستعمال ال WebSockets أصبحنا قادرين على إرسال إشعارات وتحديث نتائج التصويت في كل مرة يتلقى فيها الخادم أخبارا بأن هناك تغييرا ما حصل، مثلا باستعمال نمط Publish/Subscribe.
وبالعودة إلى مثال الجنرال والجنود، فهنا لم يعد الجنود مضطرين للإستسفسار عن الجديد من الجنرال لأن هذا الأخير سيكون عنده جهاز اتصال، راديو مثلا، يستعمله لإعطاء جنوده الأوامر فقط في حالة ما إذا كانت هنالك أوامر.
إذن إذا كان تطبيقك ديناميكيا وحيويا ويتطلب تواصلا حيا ومستمرا بين الخادم والمستعمل (Real time Application)، مثلا تطبيق تشات Chat، فاستعمال ال WebSockets يصبح أمرا لا مفر منه، أما إذا كان تطبيقك كلاسيكيا (تطبيقات REST) فآنذاك يصبح استعمال خادم ال HTTP كافيا ويفي بالغرض.