1. مقدمة موجزة إلى WebSocket
بروتوكول WebSocket هو بروتوكول جديد لـ HTML5. وهو ينفذ اتصالات كاملة بين المتصفح والخادم. تتطلب المصافحة الأولية مساعدة طلبات HTTP لإكمال المصافحة.
مع تطوير الإنترنت ، كان من الصعب تلبية بروتوكولات HTTP التقليدية للاحتياجات المعقدة بشكل متزايد لتطبيقات الويب. في السنوات الأخيرة ، مع ولادة HTML5 ، تم اقتراح بروتوكول WebSocket. إنه يدرك التواصل الكامل بين المتصفح والخادم ، ويقوم بتوسيع وظيفة الاتصال بين المتصفح والخادم ، ويمكّن الخادم من إرسال البيانات بنشاط إلى العميل.
خلفية WebSocket
يمكن تحقيق اتصال في اتجاه واحد فقط من خلال HTTP في المتصفح. يمكن أن يحاكي المذنب الاتصالات ثنائية الاتجاه إلى حد ما ، لكنه منخفض في الكفاءة ويتطلب دعمًا جيدًا من الخادم ؛ يمكن للمقبس و XMLSocket في الفلاش تحقيق التواصل الحقيقي في اتجاهين ، ويمكن استخدام هاتين وظيفتين في JavaScript من خلال جسر Ajax Flex. قد يكون من المتوقع أنه إذا تم تنفيذ WebSocket في المتصفح ، فسيحل محل التقنيتين أعلاه واستخدامه على نطاق واسع. في مواجهة هذا الموقف ، يحدد HTML5 بروتوكول WebSocket ، والذي يمكنه توفير موارد الخادم وعرض النطاق الترددي بشكل أفضل وتحقيق التواصل في الوقت الفعلي.
يتم تنفيذ بروتوكول WebSocket أيضًا في Javaee7.
نحن نعلم أن بروتوكول HTTP التقليدي عديمة الجنسية. يجب أن يبدأ العميل كل طلب (مثل المتصفح). بعد المعالجة ، يقوم الخادم بإرجاع نتيجة الاستجابة. من الصعب على الخادم إرسال البيانات بنشاط إلى العميل. هذا النوع من العميل هو الطرف النشط والخادم هو الطرف السلبي. يؤدي نموذج الويب التقليدي إلى متاعب أقل لتطبيقات الويب مع تغييرات المعلومات النادرة ، ولكنه يجلب إزعاجًا كبيرًا لتطبيقات الويب التي تتضمن معلومات في الوقت الفعلي ، مثل التطبيقات التي لها وظائف مثل الاتصالات الفورية ، وبيانات الوقت الفعلي ، ودفع الاشتراك ، وما إلى ذلك قبل اقتراح مواصفات WebSocket ، وغالبًا ما يستخدم المطورون حلول المقايضة هذه في الوقت الحقيقي للغاية: استطلاعات التصوير وبيانات الرسوم الهزلية. في الواقع ، هذا الأخير هو في الأساس نوع من الاقتراع ، ولكن تم تحسينه.
الاقتراع هو الحل الأكثر أصالة لتنفيذ تطبيقات الويب في الوقت الفعلي. تتطلب تقنية الاقتراع من العملاء إرسال طلبات إلى الخادم بشكل دوري في فترة زمنية محددة وغالبًا ما تستفسر عما إذا كانت هناك تغييرات جديدة في البيانات. من الواضح أن هذا النهج يمكن أن يؤدي إلى الكثير من الطلبات غير الضرورية ، وإهدار حركة المرور وموارد الخادم.
يمكن تقسيم تكنولوجيا المذنب إلى تقنية الاقتراع والبث الطويلة. يؤدي الاقتراع الطويل إلى تحسين تكنولوجيا الاقتراع المذكورة أعلاه ، مما يقلل من الطلبات عديمة الفائدة. يضع وقت انتهاء الصلاحية لبيانات معينة ، ويرسل طلبًا فقط إلى الخادم بعد انتهاء صلاحية البيانات ؛ هذه الآلية مناسبة للحالات التي لا تكون فيها تغييرات البيانات متكررة بشكل خاص. تشير تقنية البث عادة إلى العميل باستخدام نافذة مخفية لإنشاء اتصال طويل HTTP مع الخادم. سيقوم الخادم بتحديث حالة الاتصال باستمرار للحفاظ على اتصال HTTP طويلًا على قيد الحياة ؛ وبهذه الطريقة ، يمكن للخادم إرسال البيانات بنشاط إلى العميل من خلال هذا الاتصال الطويل ؛ قد تختبر تقنية التدفق أداء الخادم في بيئة تزامن كبيرة .
تعتمد كلتا التقنيتين على وضع الاستجابة للطلب ولا يعتبران تقنيات في الوقت الفعلي بالمعنى الحقيقي ؛ كل طلب أو استجابة لسفراتهم كمية معينة من حركة المرور على نفس معلومات الرأس ، وتعقيد التطوير مرتفع أيضًا.
مع إطلاق HTML5 ، يدرك WebSocket حقًا الاتصال في الوقت الفعلي بالويب ، مما يجعل وضع B/S لديه إمكانيات اتصال في الوقت الفعلي لوضع C/S. سير عمل WebSocket كما يلي: يرسل المتصفح طلبًا إلى الخادم لإنشاء اتصال WebSocket عبر JavaScript. بعد إنشاء اتصال WebSocket بنجاح ، يمكن للعميل والخادم نقل البيانات من خلال اتصال TCP. نظرًا لأن اتصال WebSocket هو في الأساس اتصال TCP ، فإنه لا يتطلب نقل بيانات الرأس المتكررة مع كل ناقل حركة ، وبالتالي فإن حجم نقل البيانات الخاص به أصغر بكثير من تقنية الاقتراع وتكنولوجيا المذنب. لا تقدم هذه المقالة مواصفات WebSocket بالتفصيل ، ولكنها تقدم بشكل أساسي تنفيذ WebSocket في Java Web.
قام Javaee 7 بإنشاء JSR-356: Java API لمواصفات WebSocket. العديد من حاويات الويب ، مثل Tomcat و Nginx و Jetty ، وما إلى ذلك ، تدعم WebSocket. يدعم Tomcat WebSocket منذ 7.0.27 و JSR-356 منذ 7.0.47. يجب أيضًا نشر الرمز التجريبي التالي على tomcat7.0.47 أو أعلى للتشغيل.
2. مثال WebSocket
2.1. قم بإنشاء مشروع اختبار Javaweb جديد
أضف تبعية حزمة الجرة في pom.xml
<Rependency> <roupiD> javax </rougiD> <StifactId> javaee-api </stifactid> <الإصدار>
رمز العميل (صفحة الويب الرئيسية):
<٪@ page language = "java" pageencoding = "utf-" ٪> <! doctype html> <html> <head> <stitp> tomcat تطبيق java backend websocket </title> </head> onClick = "CloseWebSocket ()"> أغلق اتصال WebSocket </button> <hr/> <div id = "message"> </div> </body> <script type = "text/javaScript {Alert ('Browser الحالي لا يدعم WebSocket')} // طريقة رد الاتصال للأخطاء في اتصال WebSocket.onerror = function () {setMessageInnerHtml ("أخطاء اتصال WebSocket في websocket") ؛ websocket.onmessage = function (event) {setMessageInnerHtml (event.data) ؛} // طريقة الاتصال المغلقة websocket.onclose = function () {setMessageInnerHtml ("WebSocket Connection مغلق") ؛} // الاستماع إلى حدث إغلاق النافذة. عند إغلاق النافذة ، تغلق بشكل نشط اتصال WebSocket لمنع الإغلاق قبل فصل الاتصال ، وسيقوم جانب الخادم بإلقاء استثناءات. window.onbeforeUnload = function () {closeWebSocket () ؛) {websocket.close () ؛} // إرسال وظيفة الرسالة send () {var message = document.getElementById ('text'). value ؛ رمز خلفية الويب Java
package me.gacl.websocket ؛ استيراد java.io.ioException ؛ استيراد java.util.concurrent.copyonwritearrayset ؛ استيراد javax.websocket. تتمثل وظيفتها بشكل أساسي في تحديد الفئة الحالية كجانب خادم WebSocket. سيتم استخدام قيمة التعليق التوضيحي للاستماع إلى اتصال المستخدم بعنوان عنوان URL للوصول الطرفي للمستخدم. يمكن للعميل الاتصال بجانب WebSocket Server من خلال عنوان URL*/@serverendpoint ("/websocket") فئة عامة websockettest {// static starials المستخدمة لتسجيل العدد الحالي للاتصالات عبر الإنترنت. يجب أن تكون مصممة لتكون آمنة الخيط. تم استخدام intinecount intinecount static int static = ؛ // مجموعة آمنة مؤشرات الترابط للحزمة المتزامنة لتخزين كائن myWebsocket المقابل لكل عميل. لإدراك أن الخادم يتواصل مع عميل واحد ، يمكنك استخدام MAP لتخزينه ، حيث يمكن للمفتاح تحديد مستخدم CopyWriteArrayset الخاص بالمستخدم الثابتة (WebSocketTest> websocketset = New CopyOnWriteArrayset <Pebsockettest> () ؛ // ، يجب إرسال جلسة الاتصال مع العميل إلى العميل من خلال جلسة الجلسة الخاصة ؛ الجلسة هي جلسة اتصال مع عميل معين ، وتحتاج إلى إرسال بيانات إلى العميل من خلاله*/@@onopenpublic void onopen (جلسة الجلسة) {this.session = session ؛ websocketset.add (this) ؛ // إضافة إلى addonLinEcount () في set ؛ // إضافة إلى System.out.println ("هناك اتصال جديد للانضمام! العدد الحالي للأشخاص عبر الإنترنت هو" + getOnlinEcount ()) ؛}/*** لتوصيل المكالمات الختامية*/@onClosepublic void onClose () {websocketset.remove (هذا) ؛ // delete subonlinecount () من set ؛ // انخفاض في نظام الأرقام عبر الإنترنت. رسالة) ؛ // رسالة دفعة لـ (websockettest العنصر: websocketset) {try {item.SendMessage (message) ؛} catch (ioException e) { خطأ) {system.out.println ("حدث خطأ") ؛ خطأ. لا يوجد أي شرح ، إنها طريقة تمت إضافتها وفقًا لاحتياجاتك. * param message* throws ioException*/public void sendmessage (رسالة سلسلة) يلقي ioException {this.session.getBasicRemote (). sendText (message) ؛ // this.session.getasyncremote (). addonlinecount () {websockettest.onlinecount ++ ؛} public static static void subonlinecount () {websockettest.onlinecount-- ؛}} 1.2. تأثير التشغيل
افتح متصفح Google ومتصفح Firefox في نفس الوقت لاختبارات المحاكاة متعددة الرفع. تأثير العملية على النحو التالي:
المحتوى أعلاه هو مثال البرنامج التعليمي لتطبيق WebSocket بواسطة Java Backend Tomcat المقدمة إليك. آمل أن يكون ذلك مفيدًا للجميع!