Signaling Server — یک مؤلفه سروری زیرساخت WebRTC است که تبادل فراداده بین همتاها را برای برقراری و پایان اتصال فراهم میکند. برخلاف ترافیک رسانهای، سیگنالینگ میتواند از طریق هر پروتکلی — 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، همتاها باید سه نوع پیام مبادله کنند: session description (offer و answer)، ICE candidates و اطلاعات مربوط به پایان/تغییر جلسه. Signaling Server این پیامها را بین همتاها مسیریابی میکند و از شناسههای اتاق یا کاربر برای آدرسدهی استفاده میکند. الگوی استاندارد — ایجاد «اتاقی» که دو شرکتکننده به آن متصل میشوند و سرور پیامهای هر شرکتکننده را فقط به همصحبت او بازپخش میکند.
Signaling Server پروتکل استاندارد برقراری اتصال WebRTC زیر را پیادهسازی میکند. همتاها از طریق WebSocket (یا انتقال دیگر) به سرور متصل میشوند و در اتاق ثبت نام میکنند. همتا A (آغازگر) از طریق RTCPeerConnection.createOffer() یک offer (توضیحات SDP جریان رسانه خروجی) ایجاد میکند، آن را به عنوان local description تنظیم میکند و به Signaling Server میفرستد. سرور offer را به همتا B بازپخش میکند. همتا B offer را دریافت میکند، آن را به عنوان remote description تنظیم میکند، از طریق createAnswer() یک answer ایجاد میکند، آن را به عنوان local description تنظیم میکند و از طریق سرور بازمیفرستد. این فرآیند SDP Offer/Answer نامیده میشود.
به موازات تبادل SDP، هر همتا ICE candidates (host، srflx، relay) را جمعآوری میکند و از طریق Signaling Server به همتای دیگر میفرستد. همتای راه دور کاندیداهای دریافتی را از طریق RTCPeerConnection.addIceCandidate() اضافه میکند. فرآیند ICE تمام ترکیبات کاندیداها را برای یافتن یک مسیر کارآمد بررسی میکند. پس از یافتن مسیر کارآمد (معمولاً در ۱–۵ ثانیه)، ترافیک رسانه شروع به انتقال مستقیم بین همتاها میکند و Signaling Server دیگر در انتقال داده شرکت نمیکند — نقش آن تا رویداد خدماتی بعدی (پایان تماس، تغییر کیفیت جریان) پایان مییابد.
برای آدرسدهی پیامها، Signaling Server از مکانیزم اتاقها (rooms) یا کانالها استفاده میکند. هر جلسه جدید WebRTC یک اتاق منحصربهفرد با شناسه (معمولاً UUID) ایجاد میکند. آغازگر اتاق را ایجاد میکند و منتظر اتصال همتای دوم میماند. همتای دوم از طریق کانال خارجی (مثلاً لینک دعوت) با ID به اتاق متصل میشود. سرور یک نقشه از اتاقها نگهداری میکند که هر ID به فهرستی از کلاینتهای متصل مربوط میشود. وقتی تعداد شرکتکنندگان به دو میرسد، سرور شروع به بازپخش پیامهای سیگنالینگ بین آنها میکند.
Signaling Server میتواند از پروتکلهای انتقال مختلفی استفاده کند که هر کدام مزایا و معایب خود را دارند. انتخاب پروتکل به نوع برنامه، محدودیتهای زیرساختی و الزامات سازگاری بستگی دارد. در زیر رایجترین پروتکلها و ویژگیهای آنها آورده شده است.
| پروتکل | انتقال | مزایا | معایب |
|---|---|---|---|
| WebSocket | TCP | دوطرفه کامل، تأخیر کم، تعبیه شده در مرورگرها | پیچیدگی مقیاسپذیری، مسدودسازی توسط پروکسی |
| HTTP/SSE | TCP | سازگاری با هر زیرساختی، سادگی پیادهسازی | فقط یکطرفه (سرور-کلاینت)، نیاز به Polling |
| XMPP | TCP | استاندارد شده، پشتیبانی از احراز هویت، قابل توسعه | اضافی برای سناریوهای ساده، سربار XML |
| SIP | UDP/TCP | یکپارچهسازی با VoIP و زیرساخت تلفنی | پیچیده، غیربومی برای مرورگرها |
| MQTT | TCP | سبک، کار در محیطهای IoT، publish/subscribe | نیاز به کارگزار، تأخیر اضافی |
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 را پردازش کرده و از طریق setRemoteDescription() و addIceCandidate() به RTCPeerConnection منتقل میکند. کد کلاینت همچنین SDP و ICE کاندیداهای خود را که از طریق رویدادهای onicecandidate و پس از ایجاد offer/answer از RTCPeerConnection دریافت شده، به سرور میفرستد.
Signaling Server دو نوع فراداده کلیدی را منتقل میکند: SDP (Session Description Protocol) و ICE candidates. SDP پارامترهای جریان رسانه — کدکها، نرخ نمونهبرداری، تعداد کانالها، جهت انتقال (sendrecv، sendonly، recvonly، inactive) را توصیف میکند. ICE candidates شامل آدرسهای شبکه (محلی، دریافتی از STUN، رله از TURN) هستند که همتا میتواند از طریق آنها برای اتصال در دسترس باشد.
SDP در قالب متنی حاوی جلسات و بخشهای رسانه ارائه میشود. بخش جلسه پارامترهای کلی (شناسه جلسه، نسخه، نام) را توصیف میکند، بخشهای رسانه هر جریان رسانه (صدا، ویدئو، DataChannel) را با کدک، پورت و پروتکل آن توصیف میکنند. ICE کاندیداها شامل foundation (شناسه برای گروهبندی)، priority، آدرس IP، پورت، نوع (host، srflx، relay) و پروتکل (UDP، TCP) هستند. هر candidate همچنین شامل ویژگی ufrag (username fragment) است که آن را به فرآیند ICE خاصی مرتبط میکند.
Trickle ICE برقراری اتصال WebRTC را به طور قابل توجهی加速 میبخشد. به جای انتظار برای جمعآوری کامل همه ICE کاندیداها (که ممکن است در شبکههای پیچیده ۲–۱۰ ثانیه طول بکشد)، هر کاندیدا بلافاصله پس از کشف به Signaling Server فرستاده میشود. همتای راه دور کاندیدا را دریافت میکند و بلافاصله شروع به بررسی اتصال از طریق چهارچوب ICE میکند. این کار زمان برقراری اتصال را در بیشتر موارد به ۵۰۰–۱۵۰۰ میلیثانیه کاهش میدهد.
سوالات متداول
Signaling Server — «هماهنگکننده» قبل از تماس است. به دو دستگاه کمک میکند یکدیگر را پیدا کنند و درباره نحوه ارتباط توافق کنند. پس از اینکه دستگاهها «آشنا شدند» و توافق کردند، سرور دیگر نیازی نیست — آنها مستقیماً ارتباط برقرار میکنند.
WebRTC پروتکل سیگنالینگ را تعریف نمیکند تا توسعهدهندگان بتوانند مناسبترین انتقال را انتخاب کنند. مرورگر مکانیزم داخلی برای کشف سایر کاربران ندارد — این وظیفه را Signaling Server حل میکند. این سرور به عنوان «پستچی» عمل میکند و دعوتنامهها و تنظیمات اتصال را بین شرکتکنندگان تماس منتقل میکند.
WebSocket — انتخاب بهینه برای اکثر برنامههای وب: دوطرفه کامل، پشتیبانی بومی توسط مرورگرها، پیادهسازی ساده. برای یکپارچهسازی با زیرساخت VoIP موجود، SIP را انتخاب کنید. برای برنامههای چت با ویژگیهای غنی — XMPP. برای سناریوهای IoT — MQTT.
برای مقیاسپذیری Signaling Server از مقیاسپذیری افقی با همگامسازی از طریق Redis Pub/Sub یا Kafka استفاده کنید. هر نمونه سرور سهم خود از اتصالات WebSocket را پردازش میکند و برای مسیریابی بین سروری پیامها از یک گذرگاه داده مشترک استفاده میشود. این رویکرد امکان پردازش میلیونها جلسه سیگنالینگ همزمان را فراهم میکند.
Signaling Server فقط در مرحله برقراری اتصال حیاتی است. اگر سرور به طور موقت در دسترس نباشد، تماسهای فعال WebRTC ادامه مییابند — ترافیک رسانه مستقیماً بین همتاها جریان دارد. مشکل فقط هنگام تلاش برای برقراری اتصال جدید رخ میدهد. برای قابلیت اطمینان، از خوشهبندی سرورها و کانالهای سیگنالینگ پشتیبان استفاده کنید.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.