Signaling Server — je serverová komponenta infrastruktury WebRTC, která zajišťuje výměnu metadat mezi peery pro navázání a ukončení spojení. Na rozdíl od mediálního provozu může být signalizace přenášena jakýmkoli protokolem — WebSocket, HTTP, XMPP nebo SIP. Podle MDN Web Docs, 2024 je signalizace povinnou součástí každé aplikace WebRTC, protože protokol nedefinuje konkrétní způsob výměny signalizačních zpráv.
Hlavní body
Signaling Server — je síťová služba odpovědná za koordinaci procesu navazování WebRTC spojení mezi dvěma nebo více peery. Nepřenáší mediální data (audio, video, data kanálu DataChannel), ale pouze servisní informace nezbytné pro objevování peerů a dohodu na parametrech spojení. Po úspěšném navázání P2P kanálu již Signaling Server nemusí být potřeba, ale v některých architekturách zůstává pro pozdější výměnu signálů (např. ukončení hovoru, přidání účastníků).
Architektura signalizace zahrnuje tři komponenty: Signaling Server, Signal Channel (transportní protokol mezi klientem a serverem) a klientské API (obvykle vestavěné do WebRTC zásobníku prohlížeče). Specifikace WebRTC (W3C, 2024) záměrně nestandardizuje signalizační protokol — vývojáři si mohou vybrat jakýkoli transport vhodný pro jejich aplikaci. Toto flexibilní řešení umožňuje použít WebSocket pro webové aplikace, XMPP pro chatovací systémy nebo SIP pro integraci s telekomunikační infrastrukturou.
Před navázáním WebRTC spojení si musí peery vyměnit tři typy zpráv: session description (offer a answer), ICE candidates a informace o ukončení/změně relace. Signaling Server tyto zprávy směruje mezi peery pomocí identifikátorů místností nebo uživatelů pro adresaci. Standardní vzor — vytvoření „místnosti“, do které se připojí dva účastníci, a server přeposílá zprávy od každého účastníka pouze jeho partnerovi.
Signaling Server implementuje následující typický protokol navazování WebRTC spojení. Peery se připojí k serveru přes WebSocket (nebo jiný transport) a zaregistrují se v místnosti. Peer A (iniciátor) vytvoří offer (SDP popis odchozího mediálního toku) přes RTCPeerConnection.createOffer(), nastaví jej jako local description a odešle na Signaling Server. Server přepošle offer peeru B. Peer B obdrží offer, nastaví jej jako remote description, vytvoří answer přes createAnswer(), nastaví jej jako local description a odešle zpět přes server. Tento proces se nazývá SDP Offer/Answer.
Současně s výměnou SDP každý peer shromažďuje ICE candidates (host, srflx, relay) a odesílá je přes Signaling Server druhému peeru. Vzdálený peer přidá obdržené kandidáty přes RTCPeerConnection.addIceCandidate(). Proces ICE kontroluje všechny kombinace kandidátů, aby našel fungující cestu. Po nalezení fungující cesty (obvykle během 1–5 sekund) začne mediální provoz proudit přímo mezi peery a Signaling Server se již neúčastní přenosu dat — jeho role končí do další servisní události (ukončení hovoru, změna kvality toku).
Pro adresaci zpráv používá Signaling Server mechanismus místností (rooms) nebo kanálů. Každá nová WebRTC relace vytváří jedinečnou místnost s identifikátorem (obvykle UUID). Iniciátor vytvoří místnost a čeká na připojení druhého peeru. Druhý peer se připojí k místnosti pomocí ID získaného externím kanálem (např. odkazem na pozvánku). Server udržuje mapu místností, kde každému ID odpovídá seznam připojených klientů. Když počet účastníků dosáhne dvou, server začne přeposílat signalizační zprávy mezi nimi.
Signaling Server může používat různé transportní protokoly, z nichž každý má své výhody a nevýhody. Výběr protokolu závisí na typu aplikace, infrastrukturních omezeních a požadavcích na kompatibilitu. Níže jsou uvedeny nejběžnější protokoly a jejich charakteristiky.
| Protokol | Transport | Výhody | Nevýhody |
|---|---|---|---|
| WebSocket | TCP | Plný duplex, nízká latence, vestavěný v prohlížečích | Složitost škálování, blokování proxy |
| HTTP/SSE | TCP | Kompatibilita s jakoukoli infrastrukturou, jednoduchost implementace | Pouze jednosměrný (server-klient), vyžaduje Polling |
| XMPP | TCP | Standardizovaný, podpora autentizace, rozšiřitelný | Zbytečný pro jednoduché scénáře, režie XML |
| SIP | UDP/TCP | Integrace s VoIP a telefonní infrastrukturou | Složitý, není nativní pro prohlížeče |
| MQTT | TCP | Lehký, funguje v IoT prostředích, publish/subscribe | Vyžaduje brokera, dodatečná latence |
WebSocket je nejoblíbenějším protokolem pro Signaling Server ve webových aplikacích. Poskytuje plně duplexní komunikaci, důležitou pro asynchronní výměnu SDP a ICE kandidátů, a je nativně podporován všemi moderními prohlížeči přes WebSocket API. Serverová implementace WebSocket je dostupná na všech populárních platformách (Node.js, Python, Java, Go). Pro aplikace s miliony uživatelů se používají škálovatelná WebSocket řešení založená na Redis Pub/Sub nebo Kafka pro synchronizaci mezi instancemi Signaling Server.
Podívejme se na jednoduchou implementaci Signaling Server v Node.js s použitím knihovny ws (WebSocket) a vestavěného HTTP serveru. Server podporuje registraci uživatelů, vytváření místností a přeposílání zpráv mezi účastníky.
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);
}
Tento Signaling Server implementuje základní funkcionalitu: připojení k místnosti, přeposílání WebRTC zpráv (offer, answer, ice-candidate) mezi dvěma peery a správu odpojení. Server používá Map pro ukládání místností s připojenými WebSocket klienty. Funkce relayToPeer odesílá zprávu všem účastníkům místnosti kromě odesílatele. Pro produkci je třeba přidat potvrzení typů zpráv, zpracování chyb parsování JSON a mechanismus heartbeat pro detekci přerušených spojení.
Na straně klienta se Signaling Server integruje přes WebSocket API prohlížeče. Klient naváže spojení se serverem, odešle požadavek na připojení k místnosti a poté zpracovává příchozí WebRTC zprávy, předávajíc je do RTCPeerConnection přes setRemoteDescription() a addIceCandidate(). Klientský kód také odesílá na server své SDP a ICE kandidáty získané z RTCPeerConnection přes události onicecandidate a po vytvoření offer/answer.
Signaling Server přenáší dva klíčové typy metadat: SDP (Session Description Protocol) a ICE candidates. SDP popisuje parametry mediálního toku — kodeky, vzorkovací frekvenci, počet kanálů, směr přenosu (sendrecv, sendonly, recvonly, inactive). ICE candidates obsahují síťové adresy (lokální, získané ze STUN, relay z TURN), na kterých může být peer dosažitelný pro spojení.
SDP je prezentováno v textovém formátu obsahujícím relace a mediální sekce. Část relace popisuje obecné parametry (identifikátor relace, verze, název), mediální sekce — každý mediální tok (audio, video, DataChannel) s jeho kodekem, portem a protokolem. ICE kandidáti obsahují foundation (identifikátor pro seskupování), priority, IP adresu, port, typ (host, srflx, relay) a protokol (UDP, TCP). Každý kandidát také obsahuje atribut ufrag (username fragment), který jej spojuje s konkrétním ICE procesem.
Trickle ICE výrazně urychluje navazování WebRTC spojení. Místo čekání na úplný sběr všech ICE kandidátů (což může ve složitých sítích trvat 2–10 sekund) je každý kandidát odeslán na Signaling Server ihned po objevení. Vzdálený peer obdrží kandidáta a okamžitě zahájí kontrolu spojení přes framework ICE. To zkracuje dobu navazování spojení na 500–1500 ms ve většině případů.
Často kladené otázky
Signaling Server — je „koordinátor“ před hovorem. Pomáhá dvěma zařízením najít se navzájem a dohodnout se, jak budou komunikovat. Poté, co se zařízení „seznámí“ a dohodnou, server již není potřeba — komunikují přímo.
WebRTC nedefinuje signalizační protokol, aby si vývojáři mohli vybrat nejvhodnější transport. Prohlížeč nemá vestavěný mechanismus pro objevování ostatních uživatelů — tento úkol řeší Signaling Server. Slouží jako „pošťák“, přenášející pozvánky a nastavení spojení mezi účastníky hovoru.
WebSocket — optimální volba pro většinu webových aplikací: plně duplexní, nativně podporovaný prohlížeči, jednoduchý na implementaci. Pro integraci se stávající VoIP infrastrukturou zvolte SIP. Pro chatovací aplikace s bohatými funkcemi — XMPP. Pro IoT scénáře — MQTT.
Pro škálování Signaling Server použijte horizontální škálování se synchronizací přes Redis Pub/Sub nebo Kafka. Každá instance serveru zpracovává svůj díl WebSocket spojení a pro meziserverové směrování zpráv se používá společná datová sběrnice. Tento přístup umožňuje zpracovávat miliony současných signalizačních relací.
Signaling Server je kritický pouze ve fázi navazování spojení. Pokud je server dočasně nedostupný, aktivní WebRTC hovory pokračují — mediální provoz jde přímo mezi peery. Problém nastává pouze při pokusu o navázání nového spojení. Pro spolehlivost použijte clustering serverů a záložní signalizační kanály.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také