Signaling Server — är en serverkomponent i WebRTC-infrastrukturen som möjliggör utbyte av metadata mellan peers för att upprätta och avsluta en anslutning. Till skillnad från mediatrafik kan signalering överföras via vilket protokoll som helst — WebSocket, HTTP, XMPP eller SIP. Enligt MDN Web Docs, 2024 är signalering en obligatorisk komponent i alla WebRTC-applikationer eftersom protokollet inte definierar något specifikt sätt att utbyta signaleringsmeddelanden.
Huvudpunkter
Signaling Server — är en nätverkstjänst som ansvarar för att samordna processen att upprätta en WebRTC-anslutning mellan två eller flera peers. Den överför inte mediadata (ljud, video, DataChannel-data) utan endast tjänsteinformation som behövs för att upptäcka peers och förhandla om anslutningsparametrar. Efter att P2P-kanalen framgångsrikt upprättats kan Signaling Server inte längre behövas, men i vissa arkitekturer kvarstår den för efterföljande signalutbyte (till exempel avsluta samtal, lägga till deltagare).
Signaleringsarkitekturen omfattar tre komponenter: Signaling Server, Signal Channel (transportprotokoll mellan klient och server) och klient-API (vanligtvis inbäddat i webbläsarens WebRTC-stack). WebRTC-specifikationen (W3C, 2024) standardiserar avsiktligt inte signaleringsprotokollet — utvecklare kan välja vilken transport som helst som passar deras applikation. Denna flexibla lösning gör det möjligt att använda WebSocket för webbapplikationer, XMPP för chatt-system eller SIP för integration med telekommunikationsinfrastruktur.
Innan WebRTC-anslutningen upprättas måste peers utbyta tre typer av meddelanden: session description (offer och answer), ICE candidates och information om avslutning/ändring av sessionen. Signaling Server dirigerar dessa meddelanden mellan peers med hjälp av rums- eller användaridentifikatorer för adressering. Standardmönstret — att skapa ett “rum” som två deltagare ansluter till, och servern vidarebefordrar meddelanden från varje deltagare endast till dess samtalspartner.
Signaling Server implementerar följande typiska protokoll för att upprätta en WebRTC-anslutning. Peers ansluter till servern via WebSocket (eller annan transport) och registrerar sig i ett rum. Peer A (initiativtagaren) skapar ett offer (SDP-beskrivning av den utgående mediaströmmen) via RTCPeerConnection.createOffer(), anger det som local description och skickar det till Signaling Server. Servern vidarebefordrar offert till peer B. Peer B tar emot offert, anger det som remote description, skapar ett answer via createAnswer(), anger det som local description och skickar tillbaka det via servern. Denna process kallas SDP Offer/Answer.
Parallellt med SDP-utbytet samlar varje peer in ICE candidates (host, srflx, relay) och skickar dem via Signaling Server till den andra peern. Den fjärranslutna peern lägger till de mottagna kandidaterna via RTCPeerConnection.addIceCandidate(). ICE-processen kontrollerar alla kombinationer av kandidater för att hitta en fungerande väg. När en fungerande väg har hittats (vanligtvis inom 1–5 sekunder) börjar mediatrafik överföras direkt mellan peers, och Signaling Server deltar inte längre i dataöverföringen — dess roll är avslutad fram till nästa tjänstehändelse (avsluta samtal, ändra strömkvalitet).
För adressering av meddelanden använder Signaling Server en mekanism med rum (rooms) eller kanaler. Varje ny WebRTC-session skapar ett unikt rum med en identifierare (vanligtvis UUID). Initiativtagaren skapar rummet och väntar på att den andra peern ska ansluta. Den andra peern ansluter till rummet via ett ID som erhållits via en extern kanal (till exempel en inbjudningslänk). Servern upprätthåller en karta över rum där varje ID motsvarar en lista över anslutna klienter. När antalet deltagare når två börjar servern att vidarebefordra signaleringsmeddelanden mellan dem.
Signaling Server kan använda olika transportprotokoll, var och en med sina egna fördelar och nackdelar. Valet av protokoll beror på applikationstyp, infrastrukturbegränsningar och kompatibilitetskrav. Nedan visas de vanligaste protokollen och deras egenskaper.
| Protokoll | Transport | Fördelar | Nackdelar |
|---|---|---|---|
| WebSocket | TCP | Full duplex, låg latens, inbyggt i webbläsare | Skalningskomplexitet, proxy-blockering |
| HTTP/SSE | TCP | Kompatibilitet med alla infrastrukturer, enkel implementering | Endast enkelriktat (server-klient), kräver Polling |
| XMPP | TCP | Standardiserat, stöd för autentisering, utbyggbart | Överflödigt för enkla scenarier, XML-overhead |
| SIP | UDP/TCP | Integration med VoIP och telefoninfrastruktur | Komplext, inte inbyggt för webbläsare |
| MQTT | TCP | Lättviktigt, fungerar i IoT-miljöer, publish/subscribe | Kräver broker, extra latens |
WebSocket är det mest populära protokollet för Signaling Server i webbapplikationer. Det ger full duplex-kommunikation, vilket är viktigt för asynkront utbyte av SDP- och ICE-kandidater, och stöds inbyggt av alla moderna webbläsare via WebSocket API. Serverimplementeringen av WebSocket finns på alla populära plattformar (Node.js, Python, Java, Go). För applikationer med miljontals användare används skalbara WebSocket-lösningar baserade på Redis Pub/Sub eller Kafka för synkronisering mellan Signaling Server-instanser.
Låt oss titta på en enkel implementering av Signaling Server i Node.js med hjälp av ws-biblioteket (WebSocket) och den inbyggda HTTP-servern. Servern stöder användarregistrering, skapande av rum och vidarebefordran av meddelanden mellan deltagare.
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);
}
Denna Signaling Server implementerar grundläggande funktionalitet: anslutning till rum, vidarebefordran av WebRTC-meddelanden (offer, answer, ice-candidate) mellan två peers och hantering av frånkopplingar. Servern använder Map för att lagra rum med anslutna WebSocket-klienter. Funktionen relayToPeer skickar meddelandet till alla deltagare i rummet utom avsändaren. För produktion krävs tillägg av bekräftelse av meddelandetyper, hantering av JSON-parsningsfel och en heartbeat-mekanism för att upptäcka brutna anslutningar.
På klientsidan integreras Signaling Server via webbläsarens WebSocket API. Klienten upprättar en anslutning till servern, skickar en begäran om att ansluta till ett rum och bearbetar sedan inkommande WebRTC-meddelanden genom att vidarebefordra dem till RTCPeerConnection via setRemoteDescription() och addIceCandidate(). Klientkoden skickar också sina egna SDP- och ICE-kandidater till servern, erhållna från RTCPeerConnection via händelser onicecandidate och efter att offer/answer har skapats.
Signaling Server överför två viktiga typer av metadata: SDP (Session Description Protocol) och ICE candidates. SDP beskriver parametrarna för mediaströmmen — codecs, samplingsfrekvens, antal kanaler, överföringsriktning (sendrecv, sendonly, recvonly, inactive). ICE candidates innehåller nätverksadresser (lokala, erhållna från STUN, relay från TURN) där en peer kan nås för anslutning.
SDP presenteras i textformat som innehåller sessioner och mediasektioner. Sessionsdelen beskriver allmänna parametrar (session-ID, version, namn), mediasektionerna — varje mediaström (ljud, video, DataChannel) med dess codec, port och protokoll. ICE-kandidater innehåller foundation (identifierare för gruppering), priority, IP-adress, port, typ (host, srflx, relay) och protokoll (UDP, TCP). Varje kandidat innehåller också attributet ufrag (username fragment) som kopplar det till en specifik ICE-process.
Trickle ICE påskyndar avsevärt upprättandet av WebRTC-anslutningen. Istället för att vänta på fullständig insamling av alla ICE-kandidater (vilket kan ta 2–10 sekunder i komplexa nätverk) skickas varje kandidat till Signaling Server omedelbart efter upptäckt. Den fjärranslutna peern tar emot kandidaten och börjar omedelbart testa anslutningen via ICE-ramverket. Detta minskar anslutningstiden till 500–1500 ms i de flesta fall.
Vanliga frågor
Signaling Server — är “koordinatorn” före ett samtal. Det hjälper två enheter att hitta varandra och komma överens om hur de ska kommunicera. När enheterna har “lärt känna varandra” och kommit överens behövs inte servern längre — de kommunicerar direkt.
WebRTC definierar inte signaleringsprotokollet så att utvecklare kan välja den mest lämpliga transporten. Webbläsaren har ingen inbyggd mekanism för att upptäcka andra användare — denna uppgift löses av Signaling Server. Den fungerar som en “brevbärare” och förmedlar inbjudningar och anslutningsinställningar mellan deltagare i ett samtal.
WebSocket — det optimala valet för de flesta webbapplikationer: full duplex, inbyggt stöd i webbläsare, enkelt att implementera. För integration med befintlig VoIP-infrastruktur, välj SIP. För chattapplikationer med rika funktioner — XMPP. För IoT-scenarier — MQTT.
För skalning av Signaling Server, använd horisontell skalning med synkronisering via Redis Pub/Sub eller Kafka. Varje serverinstans bearbetar sin egen del av WebSocket-anslutningarna och för kommunikation mellan servrar används en gemensam databuss. Detta tillvägagångssätt möjliggör hantering av miljontals samtidiga signaleringssessioner.
Signaling Server är endast kritisk i fasen av att upprätta anslutningen. Om servern är tillfälligt otillgänglig fortsätter aktiva WebRTC-samtal — mediatrafik går direkt mellan peers. Problemet uppstår endast när man försöker upprätta en ny anslutning. För tillförlitlighet, använd serverklustring och reservsignaleringskanaler.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också