WebSockets في JavaScript: عندما يكون الموقع "الحي" ليس سحرًا بل كودًا
\n\nهل تساءلت يومًا كيف تعمل الدردشات عبر الإنترنت، أسعار الأسهم في الوقت الفعلي، أو الألعاب متعددة اللاعبين في المتصفح؟ السر بسيط وأنيق — WebSockets في JavaScript. هذه التقنية تحول موقع الويب الثابت إلى كائن حي يتفاعل فورًا مع تصرفات المستخدمين الآخرين.
\n\nفي هذه المقالة، لن نناقش النظرية فقط. سنكتب دردشة حقيقية من الصفر، ونتعلم كيفية معالجة الأخطاء، ونفهم لماذا تطبيقات الوقت الفعلي على WebSockets تعمل أسرع من تقنية AJAX القديمة مع polling. استعدوا — سيكون الأمر ممتعًا.
\n\nلماذا HTTP غير مناسب للوقت الفعلي؟ (شرح موجز)
\n\nيعمل HTTP العادي على مبدأ "طلب-استجابة". العميل يطلب — الخادم يرد. إذا أراد الخادم أن يقول شيئًا بنفسه (مثل "وصلت رسالة جديدة")، فعليه الانتظار حتى يسأل العميل مرة أخرى. هذا يشبه المراسلة بالحمام الزاجل — بطيء وغير فعال.
\n\nابتكر المطورون حلولاً بديلة:
\n- \n
- Polling — العميل يسأل الخادم كل 5 ثوانٍ: "هل هناك أخبار؟" \n
- Long polling — الخادم يبقي الاتصال مفتوحًا حتى يظهر رد (لكنه لا يزال قناة أحادية الاتجاه). \n
وهنا تظهر WebSockets على المسرح. تخيل أنك فتحت خط هاتف بين المتصفح والخادم. يمكن لكل منهما التحدث في أي وقت، في وقت واحد، دون تأخير "رفع السماعة". هذا هو سحر JavaScript WebSocket API.
\n\nكيف يعمل WebSocket: البروتوكول، المصافحة، الرسائل
\n\nتقنيًا، WebSocket هو بروتوكول منفصل (ws:// أو wss:// للاتصال المشفر). يبدأ كل شيء بمصافحة HTTP:
\n\n- \n
- يرسل العميل طلب HTTP عادي مع رأس
Upgrade: websocket. \n - يرد الخادم: "101 Switching Protocols" — ويتم "ترقية" الاتصال إلى WebSocket. \n
- بعد ذلك — ازدواج كامل: البيانات تتدفق في كلا الاتجاهين على شكل إطارات (نص أو بيانات ثنائية). \n
في المتصفح، للعمل مع WebSocket، يُستخدم الكائن المدمج WebSocket. لا حاجة لمكتبات إضافية — JavaScript WebSocket النقي يعمل مباشرة في جميع المتصفحات الحديثة.
نكتب أول دردشة في الوقت الفعلي باستخدام JavaScript
\n\nلنقم بإنشاء دردشة بسيطة. سنكتب جانب الخادم باستخدام Node.js مع مكتبة ws (الأكثر شيوعًا لـ WebSocket Node.js)، والعميل باستخدام JavaScript النقي.
الخطوة 1. تثبيت الخادم
\n\nnpm init -y\nnpm install ws\n\nالخطوة 2. كود الخادم (server.js)
\n\nconst WebSocket = require('ws');\n\nconst wss = new WebSocket.Server({ port: 8080 });\n\nwss.on('connection', function connection(ws) {\n console.log('مستخدم جديد متصل');\n\n // إرسال ترحيب للعميل الجديد\n ws.send(JSON.stringify({\n type: 'system',\n message: 'مرحبًا بك في الدردشة!'\n }));\n\n // استقبال الرسائل من العميل\n ws.on('message', function incoming(data) {\n const message = JSON.parse(data);\n console.log('تم الاستلام:', message);\n\n // بث الرسالة لجميع العملاء المتصلين\n wss.clients.forEach(function each(client) {\n if (client.readyState === WebSocket.OPEN) {\n client.send(JSON.stringify({\n type: 'message',\n user: message.user,\n text: message.text,\n time: new Date().toLocaleTimeString()\n }));\n }\n });\n });\n\n // معالجة قطع الاتصال\n ws.on('close', function() {\n console.log('مستخدم قطع الاتصال');\n });\n});\n\nconsole.log('الخادم يعمل على ws://localhost:8080');\n\n