Signaling Server — هو مكون خادم من بنية WebRTC الأساسية ي facilit تبادل البيانات الوصفية بين الأقران لإنشاء وإنهاء الاتصال. على عكس حركة الوسائط، يمكن نقل الإشارات عبر أي بروتوكول — WebSocket أو HTTP أو XMPP أو SIP. وفقًا لـ MDN Web Docs، 2024، تعد الإشارات مكونًا إلزاميًا لأي تطبيق WebRTC، لأن البروتوكول لا يحدد طريقة محددة لتبادل رسائل الإشارات.
النقاط الرئيسية
Signaling Server — هو خدمة شبكية مسؤولة عن تنسيق عملية إنشاء اتصال WebRTC بين قرينين أو أكثر. لا ينقل بيانات الوسائط (الصوت، الفيديو، بيانات DataChannel)، بل فقط المعلومات التحكمية اللازمة لاكتشاف الأقران والتفاوض على معلمات الاتصال. بعد إنشاء قناة P2P بنجاح، قد لا يكون Signaling Server ضروريًا بعد الآن، لكن في بعض البنى يبقى لتبادل الإشارات اللاحق (مثل إنهاء المكالمة، إضافة مشاركين).
تشمل بنية الإشارات ثلاثة مكونات: Signaling Server، Signal Channel (بروتوكول النقل بين العميل والخادم) و API العميل (عادةً ما يكون مدمجًا في مجموعة WebRTC للمتصفح). لا تقوم مواصفات WebRTC (W3C، 2024) بتوحيد بروتوكول الإشارات عمدًا — يمكن للمطورين اختيار أي نقل مناسب لتطبيقهم. يسمح هذا النهج المرن باستخدام WebSocket للتطبيقات الويب، XMPP لأنظمة الدردشة أو SIP للتكامل مع بنية الاتصالات.
قبل إنشاء اتصال WebRTC، يجب على الأقران تبادل ثلاثة أنواع من الرسائل: أوصاف الجلسة (offer و answer)، مرشحي ICE ومعلومات إنهاء/تعديل الجلسة. يقوم Signaling Server بتوجيه هذه الرسائل بين الأقران باستخدام معرفات الغرف أو المستخدمين للعنونة. النمط القياسي هو إنشاء «غرفة» حيث يتصل مشاركان، ويقوم الخادم بإعادة توجيه الرسائل من كل مشارك فقط إلى نظيره.
Signaling Server ينفذ بروتوكول إنشاء اتصال WebRTC النموذجي التالي. يتصل الأقران بالخادم عبر WebSocket (أو نقل آخر) ويسجلون في غرفة. يقوم القرين A (البادئ) بإنشاء offer (وصف SDP لتدفق الوسائط الصادر) عبر RTCPeerConnection.createOffer()، ويعيّنه كوصف محلي ويرسله إلى Signaling Server. يعيد الخادم توجيه offer إلى القرين B. يستلم القرين B ال offer، ويعيّنه كوصف بعيد، وينشئ answer عبر createAnswer()، ويعيّنه كوصف محلي ويرسله مرة أخرى عبر الخادم. تسمى هذه العملية تبادل SDP Offer/Answer.
بالتوازي مع تبادل SDP، يجمع كل قرين مرشحي ICE (host، srflx، relay) ويرسلهم عبر Signaling Server إلى القرين الآخر. يضيف القرين البعيد المرشحين المستلمين عبر RTCPeerConnection.addIceCandidate(). تختبر عملية ICE جميع تركيبات المرشحين للعثور على مسار عامل. بمجرد العثور على مسار عامل (عادةً خلال 1–5 ثوانٍ)، يبدأ تدفق حركة الوسائط مباشرة بين الأقرين، ولم يعد Signaling Server يشارك في نقل البيانات — ينتهي دوره حتى حدث التحكم التالي (إنهاء المكالمة، تغيير جودة التدفق).
لعنونة الرسائل، يستخدم Signaling Server آلية الغرف (rooms) أو القنوات. كل جلسة WebRTC جديدة تنشئ غرفة فريدة بمعرف (عادةً UUID). البادئ ينشئ الغرفة وينتظر اتصال القرين الثاني. القرين الثاني ينضم إلى الغرفة باستخدام المعرف المستلم عبر قناة خارجية (مثل رابط دعوة). يحتفظ الخادم بخريطة للغرف، حيث يتوافق كل معرف مع قائمة العملاء المتصلين. عندما يصل عدد المشاركين إلى اثنين، يبدأ الخادم في إعادة توجيه رسائل الإشارات بينهم.
Signaling Server يمكنه استخدام بروتوكولات نقل مختلفة، لكل منها مزاياه وعيوبه. يعتمد اختيار البروتوكول على نوع التطبيق، قيود البنية التحتية ومتطلبات التوافق. فيما يلي البروتوكولات الأكثر شيوعًا وخصائصها.
| البروتوكول | النقل | المزايا | العيوب |
|---|---|---|---|
| WebSocket | TCP | ثنائي الاتجاه كامل، زمن وصول منخفض، مدمج في المتصفحات | تعقيد التوسع، حظر الوكيل |
| HTTP/SSE | TCP | متوافق مع أي بنية تحتية، بسيط في التنفيذ | أحادي الاتجاه فقط (خادم-عميل)، يتطلب استقصاء |
| XMPP | TCP | موحد، دعم المصادقة، قابل للتوسيع | مبالغ فيه للسيناريوهات البسيطة، حمل XML زائد |
| SIP | UDP/TCP | تكامل مع بنية VoIP والهاتف | معقد، غير أصلي للمتصفحات |
| MQTT | TCP | خفيف، يعمل في بيئات IoT، نشر/اشتراك | يتطلب وسيط، زمن وصول إضافي |
WebSocket هو البروتوكول الأكثر شيوعًا لـ Signaling Server في تطبيقات الويب. يوفر اتصالًا كامل الثنائية، وهو مهم للتبادل غير المتزامن لمرشحي SDP و ICE، ومدعوم أصليًا من قبل جميع المتصفحات الحديثة عبر WebSocket API. تتوفر تطبيقات خادم WebSocket على جميع المنصات الشائعة (Node.js، Python، Java، Go). للتطبيقات التي تضم ملايين المستخدمين، تُستخدم حلول WebSocket القابلة للتوسع القائمة على Redis Pub/Sub أو Kafka للمزامنة بين مثيلات Signaling Server.
دعونا نلقي نظرة على تنفيذ بسيط لـ Signaling Server في Node.js باستخدام مكتبة ws (WebSocket) وخادم HTTP المدمج. يدعم الخادم تسجيل المستخدمين وإنشاء الغرف وإعادة توجيه الرسائل بين المشاركين.
const WebSocket = require("ws");
const server = new WebSocket.Server({ port: 8080 });
const rooms = new Map();
server.on("connection", (ws) => {
ws.roomId = null;
ws.on("message", (data) => {
const msg = JSON.parse(data);
switch (msg.type) {
case "join":
handleJoin(ws, msg.roomId);
break;
case "offer":
case "answer":
case "ice-candidate":
relayToPeer(ws, msg);
break;
case "leave":
handleLeave(ws);
break;
}
});
ws.on("close", () => handleLeave(ws));
});
function handleJoin(ws, roomId) {
if (!rooms.has(roomId)) {
rooms.set(roomId, []);
}
const room = rooms.get(roomId);
room.push(ws);
ws.roomId = roomId;
if (room.length === 2) {
room[0].send(JSON.stringify({ type: "peer-joined" }));
room[1].send(JSON.stringify({ type: "peer-joined" }));
}
}
function relayToPeer(sender, msg) {
const room = rooms.get(sender.roomId);
if (!room) return;
room.forEach(peer => {
if (peer !== sender && peer.readyState === WebSocket.OPEN) {
peer.send(JSON.stringify(msg));
}
});
}
function handleLeave(ws) {
if (!ws.roomId) return;
const room = rooms.get(ws.roomId);
if (!room) return;
const idx = room.indexOf(ws);
if (idx !== -1) room.splice(idx, 1);
if (room.length === 0) rooms.delete(ws.roomId);
}
هذا Signaling Server ينفذ الوظائف الأساسية: الاتصال بغرفة، إعادة توجيه رسائل WebRTC (offer، answer، ice-candidate) بين قرينين وإدارة قطع الاتصال. يستخدم الخادم Map لتخزين الغرف مع عملاء WebSocket المتصلين. ترسل وظيفة relayToPeer رسالة إلى جميع المشاركين في الغرفة باستثناء المرسل. للإنتاج، ستحتاج إلى إضافة التحقق من أنواع الرسائل ومعالجة أخطاء تحليل JSON وآلية heartbeat للكشف عن الاتصالات المقطوعة.
على جانب العميل، يتم دمج Signaling Server عبر WebSocket API للمتصفح. ينشئ العميل اتصالاً بالخادم، ويرسل طلبًا للانضمام إلى غرفة، ثم يعالج رسائل WebRTC الواردة، مرررًا إياها إلى RTCPeerConnection عبر setRemoteDescription() و addIceCandidate(). يرسل كود العميل أيضًا مرشحي SDP و ICE الخاصة به إلى الخادم، المستلمة من RTCPeerConnection عبر حدث onicecandidate وبعد إنشاء offer/answer.
Signaling Server ينقل نوعين رئيسيين من البيانات الوصفية: SDP (Session Description Protocol) ومرشحي ICE. يصف SDP معلمات تدفق الوسائط — الترميزات، معدل العينات، عدد القنوات، اتجاه الإرسال (sendrecv، sendonly، recvonly، inactive). تحتوي مرشحات ICE على عناوين الشبكة (محلية، مستلمة من STUN، مرحّلة من TURN) التي يمكن من خلالها الوصول إلى القرين للاتصال.
يُعرض SDP بتنسيق نصي يحتوي على أقسام الجلسة والوسائط. يصف جزء الجلسة المعلمات العامة (معرف الجلسة، الإصدار، الاسم)، بينما تصف أقسام الوسائط كل تدفق وسائط (صوت، فيديو، DataChannel) مع ترميزه ومنفذه وبروتوكوله. مرشحو ICE يحتوي على foundation (معرف التجميع)، الأولوية، عنوان IP، المنفذ، النوع (host، srflx، relay) والبروتوكول (UDP، TCP). يتضمن كل مرشح أيضًا سمة ufrag (جزء اسم المستخدم) التي تربطه بعملية ICE محددة.
Trickle ICE يسرع بشكل كبير إنشاء اتصال WebRTC. بدلاً من انتظار التجميع الكامل لجميع مرشحي ICE (الذي قد يستغرق 2–10 ثوانٍ في الشبكات المعقدة)، يتم إرسال كل مرشح إلى Signaling Server فور اكتشافه. يستلم القرين البعيد المرشح ويبدأ فورًا اختبار الاتصال عبر إطار ICE. يقلل هذا وقت إنشاء الاتصال إلى 500–1500 مللي ثانية في معظم الحالات.
الأسئلة الشائعة
Signaling Server — هو «المنسق» قبل المكالمة. يساعد جهازين في العثور على بعضهما البعض والاتفاق على كيفية تواصلهما. بمجرد أن «يتعرف» الجهازان على بعضهما ويتفقان، لم يعد الخادم ضروريًا — يتواصلان مباشرة.
WebRTC لا يحدد بروتوكول إشارات حتى يتمكن المطورون من اختيار النقل الأكثر ملاءمة. المتصفح لا يحتوي على آلية مدمجة لاكتشاف المستخدمين الآخرين — هذه المهمة يقوم بها Signaling Server. يعمل كـ«ساعي بريد»، يسلم الدعوات وإعدادات الاتصال بين المشاركين في المكالمة.
WebSocket — هو الخيار الأمثل لمعظم تطبيقات الويب: ثنائي الاتجاه كامل، مدعوم أصليًا من المتصفحات، وبسيط في التنفيذ. للتكامل مع بنية VoIP الحالية، اختر SIP. لتطبيقات الدردشة الغنية بالميزات، استخدم XMPP. لسيناريوهات IoT، استخدم MQTT.
لـ توسعة Signaling Server، استخدم التوسع الأفقي مع المزامنة عبر Redis Pub/Sub أو Kafka. كل مثيل خادم يعالج حصته من اتصالات WebSocket، ويتم استخدام ناقل بيانات مشترك لتوجيه الرسائل بين الخوادم. يسمح هذا النهج بمعالجة ملايين جلسات الإشارات المتزامنة.
Signaling Server مهم فقط خلال مرحلة إنشاء الاتصال. إذا أصبح الخادم غير متاح مؤقتًا، تستمر مكالمات WebRTC النشطة — تدفق حركة الوسائط يحدث مباشرة بين الأقران. تنشأ المشكلة فقط عند محاولة إنشاء اتصال جديد. للموثوقية، استخدم تجميع الخوادم وقنوات إشارات احتياطية.
الخلاصة
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.