ICE Candidate — is een element van de WebRTC-infrastructuur dat een potentieel netwerkadres (IP + poort) vertegenwoordigt voor het tot stand brengen van een P2P-verbinding tussen apparaten. Elke kandidaat beschrijft een beschikbaar transportpad dat kan worden gebruikt voor het verzenden van mediadata. In het ICE-proces (Interactive Connectivity Establishment) wisselen apparaten lijsten met kandidaten uit, testen ze en kiezen de optimale route. Volgens Mozilla MDN, 2026 is ICE Candidate een sleutelcomponent van de WebRTC-stack, die verbinding garandeert in complexe netwerkomstandigheden.
Belangrijkste punten
ICE Candidate (Interactive Connectivity Establishment Candidate) — is een fundamentele eenheid in het proces van het tot stand brengen van een P2P-verbinding via het WebRTC-protocol. Het vertegenwoordigt een IP-adres + poort-paar dat kan worden gebruikt voor gegevensoverdracht tussen twee peers. Elke kandidaat bevat informatie over het transportprotocol (UDP, TCP), het type verbinding en de prioriteit.
ICE Candidate wordt op elk apparaat afzonderlijk gevormd. Het apparaat verzamelt alle beschikbare netwerkinterfaces, vraagt het externe adres op via een STUN-server en voegt een relay-adres toe van de TURN-server. De resulterende lijst met kandidaten wordt naar de externe peer gestuurd via een signaleringskanaal in SDP-formaat (Session Description Protocol).
Volgens de specificatie RFC 8445 (IETF, 2018) gebruikt ICE het nominated pairs-mechanisme: na het verzamelen van alle kandidaten worden ze paarsgewijs getest via STUN-verzoeken. Het eerste paar dat de test doorstaat, wordt nominated (aangewezen) en gebruikt voor multimediagegevens. De overige paren blijven in reserve voor het geval de verbinding wordt verbroken.
WebRTC — is een open standaard voor P2P-communicatie, maar directe verbinding tussen apparaten is vaak onmogelijk vanwege NAT (Network Address Translation) en firewalls. ICE Candidate lost dit probleem op door meerdere alternatieve verbindingspaden aan te bieden. Het ICE-protocol (Interactive Connectivity Establishment) is een verplichte component van WebRTC en wordt beschreven in de W3C WebRTC-specificatie (2025).
Veel mobiele app-ontwikkelaars gebruiken WebRTC-bibliotheken zoals Google WebRTC (voor Android) en native wrappers voor iOS. In elk daarvan wordt het ICE-proces automatisch beheerd, maar inzicht in de typen kandidaten stelt de ontwikkelaar in staat de serverinfrastructuur te configureren en de verbindingskwaliteit te optimaliseren.
ICE Candidate wordt verzonden in een SDP-bericht als a=candidate-attributen. Elke regel bevat foundation, component-ID, transportprotocol, prioriteit, IP-adres, poort en het type kandidaat. Hieronder staat een voorbeeld van een SDP-fragment met drie kandidaten van verschillende typen:
// Voorbeeld SDP met ICE-kandidaten
a=candidate:1 1 UDP 2130706431 192.168.1.10 54321 typ host
a=candidate:2 1 UDP 1694498815 203.0.113.5 54322 typ srflx
a=candidate:3 1 TCP 1019212287 198.51.100.7 54323 typ relay raddr 203.0.113.5 rport 3478
Het veld priority bepaalt de volgorde waarin kandidaten worden getest. Hoe hoger de prioriteit, hoe eerder de kandidaat wordt gecontroleerd. Host-kandidaten hebben altijd de hoogste prioriteit, relay de laagste.
Specificatie RFC 8445 definieert vier typen ICE-kandidaten, die elk overeenkomen met een specifieke manier om de externe peer te bereiken. Het type kandidaat beïnvloedt de prioriteit, de tijd om de verbinding tot stand te brengen en de vereisten voor de serverinfrastructuur.
| Type | Prioriteit | Bron | Afhankelijkheid van server |
|---|---|---|---|
| host | Hoogste | Lokale netwerkinterface | Nee |
| srflx | Hoog | STUN-reflexie | STUN |
| prflx | Gemiddeld | Peer-reflexie (in ICE-proces) | Nee |
| relay | Laagste | TURN-server | TURN |
Host-kandidaat wordt gevormd uit het IP-adres van de lokale netwerkinterface van het apparaat. Als het apparaat zich in hetzelfde lokale netwerk als de peer bevindt, biedt de host-kandidaat een directe verbinding met minimale vertraging. Voor mobiele apparaten worden host-kandidaten gegenereerd voor de WiFi-interface, mobiele LTE/5G-verbinding en indien nodig voor VPN-tunnels.
Host-kandidaten hebben de hoogste prioriteit (2130706431 voor UDP) en worden als eerste getest. Als beide peers zich achter NAT bevinden, zullen hun host-kandidaten privéadressen zijn (192.168.x.x, 10.x.x.x) en is directe verbinding via hen onmogelijk. ICE gaat over op het testen van srflx- en relay-kandidaten.
SRFLX (Server Reflexive) — is het externe IP-adres en de poort verkregen van de STUN-server. Wanneer het apparaat een STUN-verzoek verzendt, ziet de server het openbare adres na NAT en retourneert het. Deze kandidaat maakt directe verbinding mogelijk tussen peers achter verschillende NAT's, als hun NAT-apparaten Hairpinning ondersteunen.
PRFLX (Peer Reflexive) wordt dynamisch gedetecteerd wanneer een STUN-verzoek van een peer op een onverwacht adres aankomt. Dit type ontstaat wanneer beide peers tegelijkertijd verzoeken verzenden en NAT een tijdelijke binding creëert. PRFLX-kandidaat heeft een hogere prioriteit dan srflx, maar lager dan host.
In mobiele apps zijn srflx-kandidaten vooral belangrijk bij het overschakelen tussen WiFi en het mobiele netwerk. Wanneer het apparaat van netwerk wisselt, verandert het IP-adres en moet ICE de kandidaten opnieuw verzamelen. Dit proces heet ICE restart en vereist het opnieuw verzenden van een nieuwe SDP.
Relay-kandidaat — is een adres op de TURN-server waardoor verkeer wordt doorgestuurd van de ene peer naar de andere. Dit type wordt gebruikt als reserveoptie wanneer directe P2P-verbinding onmogelijk is (symmetrische NAT, bedrijfsfirewall). Het relay-kanaal voegt vertraging toe en verhoogt de serverbelasting, daarom wordt in optimale instellingen de TURN-server slechts voor 10–15% van alle sessies gebruikt.
Populaire implementaties van TURN-servers: coturn (open source), Twilio Network Traversal, Metered TURN. De keuze van de TURN-provider beïnvloedt de kwaliteit van de mediaverbinding in mobiele apps — de server moet geografisch dicht bij de gebruikers staan om extra vertraging te minimaliseren.
Het ICE-proces — is een meerfasig protocol dat de totstandbrenging van een betrouwbare P2P-verbinding garandeert in omstandigheden van onzekere netwerktopologie. Het algoritme wordt beschreven in RFC 8445 en omvat vier verplichte fasen: het verzamelen van kandidaten, het sorteren, testen en nomineren.
Elk apparaat verzamelt alle beschikbare netwerkadressen. Hiervoor inventariseert de WebRTC-engine lokale interfaces (host), stuurt een verzoek naar de STUN-server (srflx) en vraagt een relay-adres aan bij de TURN-server (relay). Tegelijkertijd kan het apparaat een prflx-kandidaat detecteren als het een inkomend STUN-verzoek van de peer ontvangt.
In mobiele ontwikkeling is deze fase van cruciaal belang voor de verbindingstijd. Op iOS en Android kan het verzamelen van kandidaten 200 ms tot 2 seconden duren, afhankelijk van de netwerksnelheid, beschikbaarheid van STUN/TURN-servers en het aantal actieve netwerkinterfaces.
Na het ontvangen van de lijst met kandidaten van de externe peer via het signaleringskanaal, vormt de lokale ICE-engine alle mogelijke paren van kandidaten (lokaal + extern). Elk paar krijgt een prioriteit volgens de formule uit RFC 8445, die rekening houdt met de prioriteiten van beide kandidaten en de richting (incoming/outgoing).
De paren worden in aflopende volgorde van prioriteit gesorteerd. De beste paren worden als eerste getest. Het algoritme garandeert dat een host-host-paar eerder wordt gecontroleerd dan host-srflx, host-relay of relay-relay, waardoor de verbindingsvertraging in eenvoudige netwerkconfiguraties wordt geminimaliseerd.
ICE verzendt STUN-binding-verzoeken voor elk paar kandidaten. Als een STUN-antwoord wordt ontvangen, is het paar geldig. Het eerste geldige paar wordt genomineerd (nominated) als primair. De WebRTC-engine begint met het verzenden van media via dit paar, terwijl de overige paren worden gecontroleerd voor het geval het primaire paar faalt.
Het testproces kan tot enkele seconden duren bij een groot aantal kandidaten. WebRTC gebruikt timers: voor host-paren een agressieve timer (20 ms), voor relay een conservatievere (200 ms). Mobiele app-ontwikkelaars kunnen de verbinding versnellen door het aantal ICE-servers te beperken of iceTransportPolicy te configureren.
ICE restart — is het herstarten van het ICE-proces zonder de hele RTCPeerConnection opnieuw aan te maken. Het is nodig bij netwerkverandering, verlies van verbinding of overschakeling tussen WiFi en mobiel netwerk. Bij een restart worden alle huidige kandidaten gereset en begint het proces opnieuw met het genereren van nieuwe ufrag en pwd.
In iOS-ontwikkeling wordt ICE restart aangeroepen met de methode restartIce() op RTCPeerConnection. Op Android wordt een vergelijkbare methode gebruikt in de klasse PeerConnection van Google WebRTC. Correcte afhandeling van ICE restart — een kritische vereiste voor apps die werken op mobiele apparaten met een onstabiele netwerkverbinding.
STUN (Session Traversal Utilities for NAT) en TURN (Traversal Using Relays around NAT) — zijn belangrijke servercomponenten zonder welke ICE Candidate geen succesvolle verbinding kan garanderen in echte internetomstandigheden. De juiste configuratie ervan heeft directe invloed op de belkwaliteit in mobiele apps.
De STUN-server stelt het apparaat in staat zijn openbare IP-adres en de poort te achterhalen die NAT heeft toegewezen voor de uitgaande verbinding. Het STUN-protocol is gedefinieerd in RFC 8489 en werkt via UDP op poort 3478 en ondersteunt ook TCP. Google biedt openbare STUN-servers (stun.l.google.com:19302) die gratis kunnen worden gebruikt.
In mobiele ontwikkeling is een STUN-verzoek — een lichte operatie die 50–200 ms duurt. Sommige bedrijfs- en mobiele netwerken blokkeren echter UDP-verkeer, waardoor ICE TCP moet gebruiken voor STUN-communicatie of direct naar TURN moet gaan.
De TURN-server — is een retransmitter van mediaverkeer. Wanneer directe P2P-verbinding onmogelijk is (symmetrische NAT, firewall), stuurt het apparaat gegevens naar TURN, die ze doorstuurt naar de andere peer. TURN is een betrouwbaar maar kostbaar mechanisme: het voegt vertraging toe (30–100 ms) en vereist bandbreedte van de server gelijk aan de som van alle mediasessies.
Volgens het WebRTC Stats Report (2025) heeft ongeveer 8–15% van de WebRTC-sessies in mobiele netwerken TURN nodig. Om de kosten van TURN-verkeer te optimaliseren, gebruiken ontwikkelaars vooraf testen van de verbinding en activeren ze alleen bij P2P-falen het TURN-kanaal.
Bij het kiezen van de infrastructuur voor ICE in een mobiel project wordt rekening gehouden met: geografische locatie van servers om vertraging te minimaliseren, ondersteuning van UDP en TCP, kosten van TURN-verkeer en SLA. Populaire oplossingen: coturn voor zelfinstallatie, Twilio, Agora en LiveKit voor cloudgebruik.
Voor mobiele ontwikkelaars gaat het begrijpen van ICE Candidate verder dan theorie — het is een praktische noodzaak bij het maken van apps met spraak- en video-oproepen. iOS- en Android-platforms bieden native API's voor WebRTC die het werk met ICE automatiseren, maar de ontwikkelaar is verantwoordelijk voor de configuratie van ICE-servers en de afhandeling van netwerkveranderingsgebeurtenissen.
Op iOS is WebRTC beschikbaar via het WebRTC.framework of de bibliotheek GoogleWebRTC via CocoaPods. ICE-servers worden geconfigureerd via de array RTCIceServer in RTCConfiguration:
let config = RTCConfiguration()
let stunServer = RTCIceServer(urlStrings: ["stun:stun.l.google.com:19302"])
let turnServer = RTCIceServer(urlStrings: ["turn:turn.example.com:3478"],
username: "user",
credential: "pass")
config.iceServers = [stunServer, turnServer]
let pc = RTCPeerConnection(configuration: config)
Na het maken van RTCPeerConnection en het aanroepen van offer() of answer(), verzamelt de engine automatisch ICE-kandidaten. De gebeurtenis iceGatheringStateChange meldt een wijziging in de verzamelstatus en iceConnectionState geeft de verbindingsstatus aan.
Android gebruikt dezelfde Google WebRTC-bibliotheek. ICE-servers worden ingesteld via PeerConnection.RTCConfiguration. De ontwikkelaar kan het ICE-beleid beheren via iceTransportsType — relay-modus dwingt het gebruik van alleen TURN af, wat de betrouwbaarheid verhoogt maar ook de vertraging:
val iceServers = listOf(
PeerConnection.IceServer.builder("stun:stun.l.google.com:19302").createIceServer(),
PeerConnection.IceServer.builder("turn:turn.example.com:3478")
.setUsername("user")
.setPassword("pass")
.createIceServer()
)
val config = PeerConnection.RTCConfiguration(iceServers)
config.iceTransportsType = PeerConnection.IceTransportsType.ALL
config.bundlePolicy = PeerConnection.BundlePolicy.MAXBUNDLE
De parameter bundlePolicy beïnvloedt het aantal ICE-kandidaten — de MAXBUNDLE-modus bundelt alle mediastromen in één transport, waardoor het totale aantal kandidaten afneemt en de verbinding sneller tot stand komt.
De belangrijkste ICE-gebeurtenissen die de ontwikkelaar moet afhandelen: ICE-verbindingsstatus (ICE connection state), wijziging van de verzamelstatus (ICE gathering state) en detectie van een nieuwe kandidaat. Nadat ICE het verzamelen en testen heeft voltooid, gaat de status naar connected of completed.
In mobiele netwerken komen vaak overschakelingen tussen WiFi en mobiele verbinding voor. Bij een netwerkwijziging moet ICE een restart uitvoeren, anders wordt de mediastroom onderbroken. Ontwikkelaars implementeren monitoring van NetworkManager (iOS) of ConnectivityManager (Android) voor het automatisch aanroepen van restartIce().
Succesvolle implementatie van ICE in een mobiele app omvat: keuze van betrouwbare STUN/TURN-servers, correcte afhandeling van ICE restart bij netwerkwijziging, configuratie van iceConnectionState voor weergave van de verbindingsstatus in de UI en monitoring van statistieken via RTCStatsReport.
Veelgestelde vragen
ICE Candidate — is een „proefadres“ voor een gesprek via WebRTC. Stel je voor dat je een vriend moet bellen, maar je weet niet waar hij is. Je probeert thuis te bellen (host), via gemeenschappelijke kennissen (STUN) en via een koerier (TURN). Elke dergelijke manier is een ICE Candidate.
Specificatie RFC 8445 onderscheidt vier typen: host (lokale interface), srflx (extern adres via STUN), prflx (dynamische kandidaat van peer) en relay (adres op TURN-server). Elk type heeft zijn eigen prioriteit en detectiemechanisme.
STUN helpt je externe IP-adres te achterhalen voor een P2P-verbinding, maar neemt niet deel aan gegevensoverdracht. TURN — is een retransmitter die mediaverkeer door zichzelf stuurt wanneer directe P2P-verbinding onmogelijk is. TURN voegt vertraging toe en verbruikt serverbandbreedte.
ICE restart is nodig bij netwerkverandering (overschakeling van WiFi naar mobiel internet), verlies van verbinding of verloop van sessie. Bij een restart worden alle huidige kandidaten gereset en begint ICE opnieuw met verzamelen met nieuwe ufrag en pwd.
Gebruik in WebRTC de methode getStats() op RTCPeerConnection, die RTCStatsReport retourneert met het veld candidateType. Op Android en iOS kun je statistieken verkrijgen over de actieve ICE-kandidaat, het type en de RTT voor het geselecteerde paar.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.