مقدمة في WebSocket على JavaScript: ما هو الاتصال في الوقت الفعلي؟
في الويب الحديث، اعتاد المستخدمون على التحديثات الفورية: تصل الرسائل في الدردشات دون إعادة تحميل الصفحة، وتتغير أسعار الأسهم في الوقت الفعلي، وتظهر إجراءات الخصوم في الألعاب عبر الإنترنت فوراً. كل هذا أصبح ممكناً بفضل تقنية WebSocket — البروتوكول الذي يوفر اتصالاً ثنائي الاتجاه مستمراً بين العميل والخادم.
على عكس طلب HTTP التقليدي، حيث يرسل العميل طلباً وينتظر الرد، يسمح WebSocket للخادم بإرسال البيانات إلى العميل بشكل مستقل في أي لحظة. هذا يفتح إمكانيات لا حصر لها لإنشاء تطبيقات الوقت الفعلي على JavaScript. في هذه المقالة، سنشرح WebSocket من الأساسيات حتى إنشاء دردشة كاملة على Node.js.
أساسيات WebSocket: كيف يعمل البروتوكول
ما هو WebSocket وكيف يختلف عن HTTP؟
WebSocket هو بروتوكول اتصال يعمل فوق TCP. يبدأ كطلب HTTP (مصافحة)، ثم يتم "ترقية" الاتصال إلى WebSocket، وتنتقل البيانات في كلا الاتجاهين دون رؤوس إضافية. هذا يجعله مثالياً للتطبيقات التي تتطلب زمن استجابة منخفض.
المزايا الرئيسية لـ WebSocket مقارنة بالطرق التقليدية (Polling، Long Polling):
- اتصال مستمر — لا حاجة لإنشاء طلب HTTP جديد لكل تحديث
- زمن استجابة منخفض — تنتقل البيانات فور ظهورها على الخادم
- توفير في حركة المرور — حجم الإطارات ضئيل (2 بايت فقط من البيانات الإدارية)
- اتصال ثنائي الاتجاه — يمكن للخادم بدء إرسال البيانات
إنشاء الاتصال: المصافحة
تبدأ العملية بطلب HTTP من العميل يحتوي على الرأس Upgrade: websocket. يستجيب الخادم الذي يدعم WebSocket بالحالة 101 Switching Protocols. بعد ذلك، يعتبر الاتصال قد تم إنشاؤه.
// مثال على طلب HTTP لإنشاء WebSocketGET /chat HTTP/1.1Host: example.comUpgrade: websocketConnection: UpgradeSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==Sec-WebSocket-Version: 13إنشاء خادم WebSocket على Node.js
تثبيت وإعداد مكتبة ws
للعمل مع WebSocket على جانب الخادم، سنستخدم المكتبة الشهيرة ws. إنها خفيفة الوزن وسريعة وتتوافق تماماً مع مواصفات البروتوكول.
// تثبيت المكتبة// npm install wsلنقم بإنشاء خادم WebSocket بسيط:
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });
wss.on('connection', (ws) => { console.log('تم اتصال عميل جديد'); ws.on('message', (message) => { console.log('تم استلام رسالة:', message.toString()); // إرسال الرد لجميع العملاء المتصلين wss.clients.forEach((client) => { if (client.readyState === WebSocket.OPEN) { client.send(`صدى: ${message}`); } }); }); ws.send('مرحباً بك في خادم WebSocket!');});
console.log('خادم WebSocket يعمل على المنفذ 8080');اتصال العميل على JavaScript
على جانب العميل (المتصفح)، يتم استخدام الكائن المدمج WebSocket:
const socket = new WebSocket('ws://localhost:8080');
socket.onopen = () => { console.log('تم إنشاء الاتصال'); socket.send('مرحباً أيها الخادم!');};
socket.onmessage = (event) => { console.log('رسالة من الخادم:', event.data);};
socket.onclose = () => { console.log('تم إغلاق الاتصال');};
socket.onerror = (error) => { console.error('خطأ في WebSocket:', error);};