Reconexão e resiliência da rede
Switches de rede e breves interrupções na conectividade podem interromper a transmissão de mídia das chamadas. O SDK lida com a reconexão automaticamente na maioria dos casos — utilize os eventos do ciclo de vida da mídia e as APIs de reconexão para manter os usuários informados e recuperar a conexão sempre que possível.
Como funciona a reconexão automática
Quando o SDK detecta uma interrupção na transmissão de mídia (falha na conexão ICE, mudança de rede), ele tenta automaticamente restaurar a conexão, reiniciando o ICE na conexão do par.
Tempo de espera e comportamento de repetição de tentativas
| Parâmetro | Valor | Descrição |
|---|---|---|
| Número máximo de tentativas automáticas | 5 | O SDK tenta novamente até 5 vezes antes de desistir |
| Intervalo entre tentativas | 3 segundos | Atraso fixo entre cada tentativa de reconexão (sem recuo exponencial) |
| Intervalo para a mídia | 10 segundos | Se nenhuma conexão for estabelecida dentro de 10s após uma tentativa de conexão, o SDK considera a tentativa como malsucedida |
| Janela de recuperação totalmente automática | ~15 segundos | 5 tentativas x intervalo de 3 s = até 15 s de recuperação automática antes da falha |
O que acontece em cada etapa
-
Reconectando-se — O SDK detecta uma interrupção na mídia e aciona
onCallMediaReconnecting. Ele realiza até 5 tentativas de reinicialização do ICE, com intervalos de 3 segundos entre elas. Não é necessária nenhuma ação por parte do desenvolvedor durante essa fase. -
Reconectado — Se alguma tentativa de repetição for bem-sucedida, o SDK é acionado
onCallMediaReconnection. O fluxo de áudio é restabelecido e a chamada continua normalmente. -
Falha — Se todas as 5 tentativas automáticas forem esgotadas, ou se o servidor retornar um erro durante a reconexão, o SDK é acionado
onCallMediaDisconnect. Neste momento:- O áudio parou
- A sessão de chamada ainda pode estar ativa no servidor
- O desenvolvedor pode tentar uma recuperação manual com
reconnectCall(callId)se a conectividade de rede tiver sido restabelecida - Se não houver recuperação, o servidor acabará encerrando a chamada e
onCallHangupincêndios commediaTimeoutmotivo
Resumo das ações do desenvolvedor
- Durante a reconexão: Não é necessária nenhuma ação. Exibir um indicador na interface do usuário informando que está “reconectando”.
- Ao ser estabelecida a reconexão com sucesso: Remova o indicador e volte à interface de chamada normal.
- Ao desligar (falha): Tentar, se desejar
reconnectCall(callId)Se você detectar que a rede voltou, avise o usuário de que a ligação foi perdida. Caso contrário, avise o usuário de que a ligação foi perdida.
Reconexão no nível da sessão
Além da reconexão de mídia, o SDK também reconecta automaticamente a sessão do WebSocket quando a conexão é interrompida:
| Parâmetro | Valor |
|---|---|
| Número máximo de tentativas de reconexão | 5 |
| Atraso na reconexão | 5 segundos (com fator de randomização de 0,75) |
Erros de reconexão de sessão onReconnecting e onReconnection eventos (diferentes dos eventos de mídia de chamada mencionados acima).
onCallMediaDisconnect
É acionado quando a conexão com a mídia é perdida definitivamente — após esgotadas todas as 5 tentativas automáticas de reconexão ou após um erro irrecuperável no servidor. Nesse momento, o fluxo de áudio foi interrompido, mas a sessão da chamada ainda pode estar ativa no servidor. Você pode tentar uma recuperação manual com reconnectCall(callId).
client.on(
'callMediaDisconnect',
(callId: string, reason: CallDisconnectReason) => {
if (reason === 'networkChange') {
console.log(`Call ${callId} was disconnected due to a network change`);
} else {
exhaustiveCheck(reason);
}
}
);
client.setOnCallMediaDisconnectListener { legId, reason ->
when (reason) {
CallDisconnectReason.networkChange -> println("Received call media disconnect $reason for Call $legId")
}
}
client.setOnCallMediaDisconnectListener((legId, reason) -> {
if (reason == CallDisconnectReason.networkChange) {
System.out.println("Received call media disconnect " + reason + " for Call " + legId);
}
return null;
});
func voiceClient(_ client: VGVoiceClient, didReceiveMediaDisconnectForCall callId: VGCallId, reason: VGCallDisconnectReason) {
print("leg \(callId) has received media disconnect for \(reason)")
}
- (void) voiceClient:(VGVoiceClient *)client didReceiveMediaDisconnectForCall:(VGCallId)callId reason:(VGCallDisconnectReason)reason {
NSLog(@"Leg %@ has received media disconnect for reason %ld", callId, reason);
}
onCallMediaReconnecting
É acionado quando o SDK detecta uma interrupção na transmissão de mídia (como uma mudança de rede entre Wi-Fi e celular) e tenta restaurar automaticamente a conexão. Não é necessária nenhuma ação do usuário — exiba um indicador de “reconectando” na sua interface do usuário.
client.on('callMediaReconnecting', (callId) => {
console.log(`Call media is reconnecting for call ${callId}`);
});
client.setOnCallMediaReconnectingListener { legId ->
println("Received call media reconnecting for Call $legId")
}
client.setOnCallMediaReconnectingListener((legId) -> {
System.out.println("Received call media reconnecting for Call " + legId);
return null;
});
func voiceClient(_ client: VGVoiceClient, didReceiveMediaReconnectingForCall callId: VGCallId) {
print("leg \(callId) is Reconnecting")
}
- (void) voiceClient:(VGVoiceClient *)client didReceiveMediaReconnectingForCall:(VGCallId)callId {
NSLog(@"Leg %@ is reconnecting", callId);
}
Reconexão de mídia em espera
É acionado quando o SDK restaura com sucesso a conexão de mídia após uma interrupção. Remova o indicador de reconexão e retorne à interface de usuário normal da chamada.
client.on('callMediaReconnection', (callId) => {
console.log(`Call media is reconnected for call ${callId}`);
});
client.setOnCallMediaReconnectionListener { legId ->
println("Received call media reconnection for Call $legId")
}
client.setOnCallMediaReconnectionListener((legId) -> {
System.out.println("Received call media reconnection for Call " + legId);
return null;
});
func voiceClient(_ client: VGVoiceClient, didReceiveMediaReconnectionForCall callId: VGCallId) {
print("leg \(callId) has received media reconnection")
}
- (void) voiceClient:(VGVoiceClient *)client didReceiveMediaReconnectionForCall:(VGCallId)callId {
NSLog(@"Leg %@ has received media reconnection", callId);
}
Reconexão manual
Uso reconnectCall(callId) quando seu aplicativo decide acionar a recuperação explicitamente — por exemplo, após receber onCallMediaDisconnect e confirmando que a conectividade de rede foi restabelecida.
A reconexão manual também segue a mesma lógica de repetição de tentativas (até 5 tentativas, com intervalos de 3 segundos) uma vez acionada.
const callId = 'callId';
await client.reconnectCall(callId);
// Callback
client.reconnectCall("callId") {
it?.let { err ->
// Handle Error in reconnecting call
println("Error in reconnecting call: $err")
}
}
// Coroutine
try {
client.reconnectCall("callId")
}
catch (e:Error) {
// Handle Error in reconnecting call
}
client.reconnectCall("callId", it -> {
if (it != null) {
// Handle Error in reconnecting call
System.out.println("Error in reconnecting call: " + it);
}
return null;
});
// Callback
client.reconnectCall("someCallId") { error in
guard error != nil else {
print("Failed to reconnect \(error?.localizedDescription ?? "")")
return
}
}
/// Async Await
Task.detached {
do {
try await client.reconnectCall("someCallId")
}
catch {
print("error")
}
}
[client reconnect:@"someCallId" callback:^(NSError * _Nullable error) {
if(error){
NSLog(@"Failed to reconnect: %@", error);
}
}];
Requisitos do Android
A recuperação automática após mudança de rede no Android requer:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
Comportamento em caso de falha e experiência do usuário
- Se todas as tentativas automáticas falharem e nenhuma reconexão manual for bem-sucedida,
onCallHangupacaba disparando commediaTimeoutrazão. - Exibir um indicador de reconexão quando
onCallMediaReconnectingincêndios. - Retorne à interface de usuário normal da chamada somente após
onCallMediaReconnectionincêndios. - Em
onCallMediaDisconnect, informar o usuário e, opcionalmente, oferecer um botão “Tentar novamente” que chamereconnectCall(callId).