Signaling Server — a WebRTC infrastruktúra szerverkomponense, amely metaadatok cseréjét biztosítja a peerek között a kapcsolat létrehozásához és befejezéséhez. A médiaforgalommal ellentétben a jelzés bármilyen protokollon keresztül továbbítható — WebSocket, HTTP, XMPP vagy SIP. A MDN Web Docs, 2024 szerint a jelzés minden WebRTC alkalmazás kötelező összetevője, mivel a protokoll nem határoz meg konkrét módot a jelzőüzenetek cseréjére.
Főbb pontok
Signaling Server — egy hálózati szolgáltatás, amely felelős a WebRTC kapcsolat létrehozásának koordinálásáért két vagy több peer között. Nem továbbít médiaadatokat (audio, video, DataChannel adatokat), csak a peerek felderítéséhez és a kapcsolati paraméterek egyeztetéséhez szükséges szolgáltatási információkat. A P2P csatorna sikeres létrehozása után a Signaling Serverre már nincs szükség, de bizonyos architektúrákban megmarad a későbbi jelcseréhez (például hívás befejezése, résztvevők hozzáadása).
A jelzés architektúrája három összetevőből áll: Signaling Server, Signal Channel (szállítási protokoll a kliens és a szerver között) és kliens API (általában a böngésző WebRTC veremébe építve). A WebRTC specifikáció (W3C, 2024) szándékosan nem szabványosítja a jelzési protokollt — a fejlesztők bármilyen, az alkalmazásukhoz megfelelő szállítást választhatnak. Ez a rugalmas megoldás lehetővé teszi a WebSocket használatát webalkalmazásokhoz, az XMPP-t csevegőrendszerekhez vagy az SIP-t a távközlési infrastruktúrával való integrációhoz.
A WebRTC kapcsolat létrehozása előtt a peereknek három típusú üzenetet kell cserélniük: session description (offer és answer), ICE candidates és információ a munkamenet befejezéséről/módosításáról. A Signaling Server ezeket az üzeneteket irányítja a peerek között, szoba- vagy felhasználóazonosítókat használva a címzéshez. A szabványos minta — egy „szoba” létrehozása, amelyhez két résztvevő csatlakozik, és a szerver minden résztvevő üzeneteit csak a beszélgetőpartnerének továbbítja.
Signaling Server a következő tipikus WebRTC kapcsolat létrehozási protokollt implementálja. A peerek WebSocketen (vagy más szállításon) keresztül csatlakoznak a szerverhez és regisztrálnak egy szobában. A Peer A (kezdeményező) létrehoz egy offer-t (a kimenő médiafolyam SDP leírását) a RTCPeerConnection.createOffer() segítségével, beállítja local description-ként és elküldi a Signaling Server-nek. A szerver továbbítja az offer-t a peer B-nek. Peer B megkapja az offer-t, beállítja remote description-ként, létrehoz egy answer-t a createAnswer() segítségével, beállítja local description-ként és visszaküldi a szerveren keresztül. Ezt a folyamatot SDP Offer/Answer-nak nevezik.
Az SDP cserével párhuzamosan minden peer gyűjti az ICE candidates-eket (host, srflx, relay) és elküldi őket a Signaling Server-en keresztül a másik peer-nek. A távoli peer hozzáadja a kapott jelölteket a RTCPeerConnection.addIceCandidate() segítségével. Az ICE folyamat ellenőrzi a jelöltek összes kombinációját egy működő útvonal megtalálásához. Miután megtalálták a működő útvonalat (általában 1–5 másodpercen belül), a médiaforgalom közvetlenül a peerek között kezd el áramlani, és a Signaling Server már nem vesz részt az adattovábbításban — szerepe a következő szolgáltatási eseményig (hívás befejezése, folyam minőségének megváltoztatása) befejeződik.
Az üzenetek címzéséhez a Signaling Server szobák (rooms) vagy csatornák mechanizmusát használja. Minden új WebRTC munkamenet létrehoz egy egyedi szobát azonosítóval (általában UUID). A kezdeményező létrehozza a szobát és várja a második peer csatlakozását. A második peer egy külső csatornán (például meghívó linken) keresztül kapott ID-val csatlakozik a szobához. A szerver fenntart egy szoba térképet, ahol minden ID-hoz a csatlakozott kliensek listája tartozik. Amikor a résztvevők száma eléri a kettőt, a szerver elkezdi továbbítani a jelzőüzeneteket közöttük.
Signaling Server különböző szállítási protokollokat használhat, amelyek mindegyikének megvannak a maga előnyei és hátrányai. A protokoll kiválasztása az alkalmazás típusától, az infrastrukturális korlátoktól és a kompatibilitási követelményektől függ. Az alábbiakban a leggyakoribb protokollok és jellemzőik találhatók.
| Protokoll | Szállítás | Előnyök | Hátrányok |
|---|---|---|---|
| WebSocket | TCP | Teljes duplex, alacsony késleltetés, böngészőkbe építve | Skálázás bonyolultsága, proxy blokkolás |
| HTTP/SSE | TCP | Kompatibilitás bármilyen infrastruktúrával, egyszerű implementáció | Csak egyirányú (szerver-kliens), Polling szükséges |
| XMPP | TCP | Szabványosított, hitelesítés támogatás, bővíthető | Felesleges egyszerű forgatókönyvekhez, XML overhead |
| SIP | UDP/TCP | Integráció VoIP és telefon infrastruktúrával | Bonyolult, nem natív a böngészőkhöz |
| MQTT | TCP | Könnyű, IoT környezetekben működik, publish/subscribe | Broker szükséges, további késleltetés |
WebSocket a legnépszerűbb protokoll a Signaling Server számára webalkalmazásokban. Teljes duplex kommunikációt biztosít, ami fontos az SDP és ICE jelöltek aszinkron cseréjéhez, és natívan támogatja minden modern böngésző a WebSocket API-n keresztül. A WebSocket szerver implementációja elérhető minden népszerű platformon (Node.js, Python, Java, Go). A milliós felhasználói bázissal rendelkező alkalmazásokhoz skálázható WebSocket megoldásokat használnak Redis Pub/Sub vagy Kafka alapú szinkronizációval a Signaling Server példányok között.
Vizsgáljuk meg egy egyszerű Signaling Server implementációt Node.js-ben a ws (WebSocket) könyvtár és a beépített HTTP szerver segítségével. A szerver támogatja a felhasználói regisztrációt, a szobák létrehozását és az üzenetek továbbítását a résztvevők között.
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);
}
Ez a Signaling Server alapvető funkcionalitást implementál: csatlakozás szobához, WebRTC üzenetek (offer, answer, ice-candidate) továbbítása két peer között és a kapcsolatok bontásának kezelése. A szerver Map-et használ a szobák tárolására a csatlakoztatott WebSocket kliensekkel. A relayToPeer függvény elküldi az üzenetet a szoba összes résztvevőjének, kivéve a feladót. Éles környezethez hozzá kell adni az üzenettípusok megerősítését, a JSON feldolgozási hibák kezelését és egy heartbeat mechanizmust a megszakadt kapcsolatok észlelésére.
Kliens oldalon a Signaling Server a böngésző WebSocket API-ján keresztül integrálódik. A kliens kapcsolatot létesít a szerverrel, elküld egy kérést a szobához való csatlakozáshoz, majd feldolgozza a bejövő WebRTC üzeneteket, továbbítva azokat a RTCPeerConnection-nek a setRemoteDescription() és addIceCandidate() segítségével. A kliens kód szintén elküldi a szervernek a saját SDP és ICE jelöltjeit, amelyeket a RTCPeerConnection-től kapott az onicecandidate eseményeken keresztül és az offer/answer létrehozása után.
Signaling Server két kulcsfontosságú metaadat típust továbbít: SDP (Session Description Protocol) és ICE candidates. Az SDP leírja a médiafolyam paramétereit — a kodekeket, mintavételezési frekvenciát, csatornák számát, adás irányát (sendrecv, sendonly, recvonly, inactive). Az ICE candidates hálózati címeket tartalmaz (helyi, STUN-tól kapott, TURN-tól relay), amelyeken a peer elérhető a kapcsolathoz.
Az SDP szöveges formátumban jelenik meg, amely munkameneteket és média szekciókat tartalmaz. A munkamenet rész leírja az általános paramétereket (munkamenet azonosító, verzió, név), a média szekciók — az egyes médiafolyamokat (audio, video, DataChannel) a kodekkel, porttal és protokollal. ICE jelöltek tartalmazzák a foundation-t (azonosító a csoportosításhoz), priority-t, IP címet, portot, típust (host, srflx, relay) és protokollt (UDP, TCP). Minden candidate tartalmazza az ufrag (username fragment) attribútumot is, amely egy adott ICE folyamathoz kapcsolja.
Trickle ICE jelentősen felgyorsítja a WebRTC kapcsolat létrehozását. Ahelyett, hogy megvárná az összes ICE jelölt teljes összegyűjtését (ami összetett hálózatokban 2–10 másodpercig is eltarthat), minden jelöltet azonnal elküld a Signaling Server-nek a felfedezése után. A távoli peer megkapja a jelöltet és azonnal megkezdi a kapcsolat ellenőrzését az ICE keretrendszeren keresztül. Ez a kapcsolat létrehozási idejét 500–1500 ms-ra csökkenti a legtöbb esetben.
Gyakran Ismételt Kérdések
Signaling Server — a „koordinátor” a hívás előtt. Segít két eszköznek megtalálni egymást és megegyezni arról, hogyan fognak kommunikálni. Miután az eszközök „megismerkedtek” és megegyeztek, a szerverre már nincs szükség — közvetlenül kommunikálnak.
WebRTC nem határozza meg a jelzési protokollt, hogy a fejlesztők kiválaszthassák a legmegfelelőbb szállítást. A böngésző nem rendelkezik beépített mechanizmussal más felhasználók felderítésére — ezt a feladatot a Signaling Server oldja meg. „Postásként” szolgál, továbbítva a meghívókat és a kapcsolat beállításait a hívás résztvevői között.
WebSocket — az optimális választás a legtöbb webalkalmazáshoz: teljes duplex, natívan támogatott a böngészők által, egyszerűen implementálható. Meglévő VoIP infrastruktúrával való integrációhoz válassza az SIP-t. Gazdag funkciójú csevegőalkalmazásokhoz — XMPP. IoT forgatókönyvekhez — MQTT.
A Signaling Server skálázásához használjon horizontális skálázást Redis Pub/Sub vagy Kafka segítségével történő szinkronizációval. Minden szerverpéldány feldolgozza a saját részét a WebSocket kapcsolatoknak, és a szerverek közötti üzenetirányításhoz közös adatbuszt használnak. Ez a megközelítés lehetővé teszi milliónyi egyidejű jelzési munkamenet feldolgozását.
Signaling Server csak a kapcsolat létrehozásának szakaszában kritikus. Ha a szerver átmenetileg nem elérhető, az aktív WebRTC hívások folytatódnak — a média forgalom közvetlenül a peerek között halad. A probléma csak új kapcsolat létrehozásakor merül fel. A megbízhatóság érdekében használjon szerver klaszterezést és tartalék jelzési csatornákat.
Összefoglalás
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is