ICE Candidate é um elemento de infraestrutura do WebRTC que representa um endereço de rede potencial (IP + porta) para estabelecer uma conexão P2P entre dispositivos. Cada candidato descreve um caminho de transporte disponível que pode ser usado para transmitir dados de mídia. Durante o processo ICE (Interactive Connectivity Establishment), os dispositivos trocam listas de candidatos, testam-nos e selecionam a rota ótima. De acordo com Mozilla MDN, 2026, o ICE Candidate é um componente chave da pilha WebRTC, garantindo conectividade em condições complexas de rede.
Principais Conclusões
ICE Candidate (Interactive Connectivity Establishment Candidate) é uma unidade fundamental no processo de estabelecimento de uma conexão P2P via protocolo WebRTC. Ele representa um par de endereço IP + porta que pode ser usado para transmissão de dados entre dois pares. Cada candidato contém informações sobre o protocolo de transporte (UDP, TCP), tipo de conexão e prioridade.
Um ICE Candidate é gerado em cada dispositivo individualmente. O dispositivo coleta todas as interfaces de rede disponíveis, solicita um endereço externo via servidor STUN e adiciona um endereço de relay do servidor TURN. A lista resultante de candidatos é enviada ao par remoto através de um canal de sinalização no formato SDP (Session Description Protocol).
De acordo com a especificação RFC 8445 (IETF, 2018), o ICE usa um mecanismo de pares nomeados: após coletar todos os candidatos, eles são testados em pares através de solicitações STUN. O par que passar na verificação primeiro é declarado nomeado e usado para transmissão multimídia. Os pares restantes permanecem na reserva em caso de queda da conexão.
WebRTC é um padrão aberto para comunicações P2P, mas uma conexão direta entre dispositivos é frequentemente impossível devido a NAT (Network Address Translation) e firewalls. O ICE Candidate resolve esse problema oferecendo vários caminhos de conexão alternativos. O protocolo ICE (Interactive Connectivity Establishment) é um componente obrigatório do WebRTC e está descrito na especificação W3C WebRTC (2025).
Muitos desenvolvedores de aplicativos móveis usam bibliotecas WebRTC como Google WebRTC (para Android) e wrappers nativos para iOS. Em cada uma delas, o processo ICE é gerenciado automaticamente, mas entender os tipos de candidatos permite ao desenvolvedor configurar a infraestrutura do servidor e otimizar a qualidade da conexão.
Um ICE Candidate é transmitido dentro de uma mensagem SDP como atributos a=candidate. Cada linha contém foundation, component ID, protocolo de transporte, prioridade, endereço IP, porta e tipo de candidato. Abaixo está um exemplo de fragmento SDP com três candidatos de diferentes tipos:
// Exemplo de SDP com candidatos ICE
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
O campo priority determina a ordem de teste dos candidatos. Quanto maior a prioridade, mais cedo o candidato será verificado. Candidatos host sempre têm a prioridade mais alta, candidatos relay a mais baixa.
A especificação RFC 8445 define quatro tipos de candidatos ICE, cada um correspondendo a uma forma específica de alcançar um par remoto. O tipo de candidato afeta sua prioridade, tempo de estabelecimento da conexão e requisitos de infraestrutura do servidor.
| Tipo | Prioridade | Origem | Dependência de servidor |
|---|---|---|---|
| host | Mais alta | Interface de rede local | Nenhuma |
| srflx | Alta | Reflexão STUN | STUN |
| prflx | Média | Reflexão de par (durante ICE) | Nenhuma |
| relay | Mais baixa | Servidor TURN | TURN |
Um candidato host é formado a partir do endereço IP da interface de rede local do dispositivo. Se o dispositivo estiver na mesma rede local que um par, o candidato host fornece uma conexão direta com latência mínima. Para dispositivos móveis, candidatos host são gerados para a interface WiFi, conexão celular LTE/5G e, se necessário, para túneis VPN.
Os candidatos host têm a prioridade mais alta (2130706431 para UDP) e são testados primeiro. Se ambos os pares estiverem atrás de NAT, seus candidatos host serão endereços privados (192.168.x.x, 10.x.x.x) e uma conexão direta através deles é impossível. O ICE então prossegue para testar candidatos srflx e relay.
Um candidato SRFLX (Server Reflexive) é um endereço IP externo e porta obtidos de um servidor STUN. Quando um dispositivo envia uma solicitação STUN, o servidor vê seu endereço público após NAT e o retorna. Este candidato permite estabelecer uma conexão direta entre pares atrás de diferentes NATs, se seus dispositivos NAT suportarem Hairpinning.
Um candidato PRFLX (Peer Reflexive) é descoberto dinamicamente quando uma solicitação STUN de um par chega a um endereço inesperado. Este tipo ocorre quando ambos os pares enviam solicitações simultaneamente e o NAT cria um vínculo temporário. Um candidato PRFLX tem prioridade mais alta que srflx, mas menor que host.
Em aplicativos móveis, candidatos srflx são especialmente importantes ao alternar entre WiFi e rede celular. Quando um dispositivo muda de rede, o endereço IP muda e o ICE deve recoletar os candidatos. Este processo é chamado de reinicialização ICE e requer o envio de um novo SDP.
Um candidato relay é um endereço em um servidor TURN através do qual o tráfego é retransmitido de um par para outro. Este tipo é usado como opção de fallback quando uma conexão P2P direta é impossível (NAT simétrico, firewall corporativo). Um canal relay adiciona latência e aumenta a carga do servidor, portanto em configurações ótimas, o servidor TURN é usado apenas para 1015% de todas as sessões.
Implementações populares de servidores TURN: coturn (código aberto), Twilio Network Traversal, Metered TURN. A escolha do provedor TURN afeta a qualidade da conexão de mídia em aplicativos móveis — o servidor deve estar geograficamente próximo aos usuários para minimizar a latência adicional.
O processo ICE é um protocolo de múltiplas etapas que garante o estabelecimento de uma conexão P2P confiável em condições de incerteza da topologia de rede. O algoritmo é descrito na RFC 8445 e inclui quatro fases obrigatórias: coleta de candidatos, classificação, teste e nomeação.
Cada dispositivo coleta todos os endereços de rede disponíveis. Para isso, o motor WebRTC enumera as interfaces locais (host), envia uma solicitação a um servidor STUN (srflx) e solicita um endereço relay a um servidor TURN. Simultaneamente, o dispositivo pode descobrir um candidato prflx se receber uma solicitação STUN de entrada de um par.
No desenvolvimento móvel, esta fase é crítica para o tempo de estabelecimento da conexão. No iOS e Android, a coleta de candidatos pode levar de 200 ms a 2 segundos dependendo da velocidade da rede, disponibilidade dos servidores STUN/TURN e número de interfaces de rede ativas.
Após receber a lista de candidatos do par remoto via canal de sinalização, o motor ICE local forma todos os pares de candidatos possíveis (local + remoto). Cada par recebe uma prioridade de acordo com a fórmula da RFC 8445, levando em conta as prioridades de ambos os candidatos e a direção (entrada/saída).
Os pares são ordenados em ordem decrescente de prioridade. Os melhores pares são testados primeiro. O algoritmo garante que um par host-host será verificado antes de host-srflx, host-relay ou relay-relay, minimizando o atraso de conexão em configurações de rede simples.
O ICE envia solicitações de ligação STUN para cada par de candidatos. Se uma resposta STUN for recebida, o par é válido. O primeiro par válido é nomeado como principal. O motor WebRTC começa a transmitir mídia por este par, enquanto os pares restantes continuam sendo verificados em caso de falha do principal.
O processo de teste pode levar até vários segundos com um grande número de candidatos. O WebRTC usa temporizadores: para pares host o temporizador é agressivo (20 ms), para pares relay — mais conservador (200 ms). Desenvolvedores de aplicativos móveis podem acelerar a conexão limitando o número de servidores ICE ou configurando iceTransportPolicy.
ICE restart é uma reinicialização do processo ICE sem recriar todo o RTCPeerConnection. É necessário ao mudar de rede, perder a conexão ou alternar entre WiFi e rede móvel. Durante um restart, todos os candidatos atuais são descartados e o processo começa novamente com a geração de novo ufrag e pwd.
No desenvolvimento iOS, o ICE restart é invocado pelo método restartIce() no RTCPeerConnection. No Android, um método similar é usado na classe PeerConnection do Google WebRTC. O tratamento adequado do ICE restart é um requisito crítico para aplicativos executados em dispositivos móveis com conexões de rede instáveis.
STUN (Session Traversal Utilities for NAT) e TURN (Traversal Using Relays around NAT) são componentes de servidor chave sem os quais o ICE Candidate não pode garantir conectividade bem-sucedida em condições reais de Internet. Sua configuração adequada afeta diretamente a qualidade da chamada em aplicativos móveis.
Um servidor STUN permite que um dispositivo descubra seu endereço IP público e a porta que o NAT alocou para a conexão de saída. O protocolo STUN é definido na RFC 8489 e opera sobre UDP na porta 3478, também suportando TCP. O Google fornece servidores STUN públicos (stun.l.google.com:19302) que podem ser usados gratuitamente.
No desenvolvimento móvel, uma solicitação STUN é uma operação leve que leva 50200 ms. No entanto, algumas redes corporativas e móveis bloqueiam tráfego UDP, forçando o ICE a usar TCP para comunicação STUN ou cair diretamente para TURN.
Um servidor TURN é um retransmissor de tráfego de mídia. Quando uma conexão P2P direta é impossível (NAT simétrico, firewall), o dispositivo envia dados para o TURN, que os encaminha para o outro par. O TURN é um mecanismo confiável, mas dispendioso: adiciona latência (30100 ms) e requer largura de banda do servidor igual à soma de todas as sessões de mídia.
De acordo com o WebRTC Stats Report (2025), cerca de 815% das sessões WebRTC em redes móveis requerem TURN. Para otimizar os custos de tráfego TURN, os desenvolvedores usam testes de conexão preliminares e ativam o canal TURN apenas se o P2P falhar.
Ao escolher a infraestrutura para ICE em um projeto móvel, são considerados: localização geográfica dos servidores para minimizar latência, suporte a UDP e TCP, custo do tráfego TURN e SLA. Soluções populares incluem: coturn para auto-hospedagem, Twilio, Agora e LiveKit para uso em nuvem.
Para desenvolvedores móveis, entender o ICE Candidate vai além da teoria — é uma necessidade prática ao criar aplicativos com chamadas de voz e vídeo. As plataformas iOS e Android fornecem APIs nativas WebRTC que automatizam o manuseio do ICE, mas o desenvolvedor é responsável por configurar os servidores ICE e lidar com eventos de mudança de rede.
No iOS, o WebRTC está disponível através do framework WebRTC.framework ou da biblioteca GoogleWebRTC via CocoaPods. Os servidores ICE são configurados através de um array de RTCIceServer no 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)
Após criar um RTCPeerConnection e chamar offer() ou answer(), o motor coleta automaticamente os candidatos ICE. O evento iceGatheringStateChange notifica sobre mudanças no status de coleta, enquanto iceConnectionState relata o status da conexão.
O Android usa a mesma biblioteca Google WebRTC. Os servidores ICE são definidos via PeerConnection.RTCConfiguration. O desenvolvedor pode gerenciar a política ICE através de iceTransportsType — o modo relay usa forçosamente apenas TURN, o que aumenta a confiabilidade mas adiciona latência:
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
O parâmetro bundlePolicy afeta o número de candidatos ICE — o modo MAXBUNDLE combina todos os fluxos de mídia em um transporte, reduzindo o número total de candidatos e acelerando a conexão.
Os principais eventos ICE que um desenvolvedor deve tratar incluem: estado da conexão ICE, estado de coleta ICE e descoberta de novo candidato. Após o ICE concluir a coleta e o teste, seu estado transita para connected ou completed.
Em redes móveis, alternâncias entre WiFi e conectividade celular são frequentes. Quando a rede muda, o ICE deve realizar um restart, caso contrário o fluxo de mídia é interrompido. Desenvolvedores implementam monitoramento do NetworkManager (iOS) ou ConnectivityManager (Android) para chamar automaticamente restartIce().
Uma implementação bem-sucedida de ICE em um aplicativo móvel inclui: escolha de servidores STUN/TURN confiáveis, tratamento adequado do ICE restart na mudança de rede, configuração de iceConnectionState para exibição do status da conexão na interface e monitoramento de estatísticas via RTCStatsReport.
Perguntas Frequentes
Um ICE Candidate é um “endereço de teste” para uma chamada WebRTC. Imagine que você precisa ligar para um amigo mas não sabe onde ele está. Você tenta ligar para casa dele (host), através de conhecidos em comum (STUN) e através de um mensageiro (TURN). Cada um desses métodos é um ICE Candidate.
A especificação RFC 8445 define quatro tipos: host (interface local), srflx (endereço externo via STUN), prflx (candidato dinâmico de um par) e relay (endereço em um servidor TURN). Cada tipo tem sua própria prioridade e mecanismo de descoberta.
STUN ajuda a descobrir seu endereço IP externo para uma conexão P2P mas não participa da transmissão de dados. TURN é um retransmissor que encaminha tráfego de mídia através de si mesmo quando uma conexão P2P direta é impossível. TURN adiciona latência e consome largura de banda do servidor.
Um ICE restart é necessário ao mudar de rede (alternar de WiFi para dados móveis), perder a conexão ou expirar o tempo da sessão. Durante um restart, todos os candidatos atuais são descartados e o ICE começa a coleta novamente com novos ufrag e pwd.
No WebRTC, use o método getStats() no RTCPeerConnection, que retorna um RTCStatsReport com o campo candidateType. No Android e iOS, você pode obter estatísticas sobre o candidato ICE ativo, seu tipo e RTT para o par selecionado.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.