04 / Journal
Tecnologia / nov. de 2026
Fazer uma chamada funcionar é fácil. Difícil é fazê-la continuar funcionando.
Chamadas de voz e vídeo parecem simples quando funcionam. No PING, os desafios reais apareceram em reconexões, estados concorrentes e segurança.
Publicado
2 de novembro de 2026
READ TIME
5 min de leitura
Há um momento muito satisfatório no desenvolvimento de chamadas: você clica em ligar, a outra pessoa atende, o áudio chega dos dois lados e a câmera funciona.
É tentador considerar a funcionalidade pronta nesse instante. Só que essa é a demonstração mais favorável possível. Os dois participantes estão disponíveis, a rede está estável, os dispositivos colaboram e nenhuma transição acontece fora de ordem.
No PING, os problemas mais interessantes começaram depois desse primeiro sucesso.
Uma chamada não é apenas uma conexão entre dois clientes. É uma experiência que precisa se manter inteligível quando as condições deixam de ser ideais.
O que a interface chama de “chamada” são várias coisas
A camada de mídia e o ciclo de vida da chamada são responsabilidades diferentes. Essa distinção ajudou a organizar o projeto.
O LiveKit fornece a infraestrutura de comunicação em tempo real sobre a qual a experiência de áudio, vídeo e compartilhamento de tela funciona. Mas ele não decide, por si só, como o PING deve convidar alguém, quanto tempo o convite permanece válido, qual dispositivo pode atender ou o que a interface mostra quando a conexão falha.
Essas decisões pertencem ao produto.
Passei a tratar o fluxo como uma máquina de estados: o convite nasce, começa a tocar, pode ser aceito, entra em conexão, torna-se uma sessão ativa e eventualmente termina. Recusa, cancelamento, expiração e erro também precisam ser transições legítimas, não exceções deixadas para depois.
Quando esses estados ficam implícitos em vários componentes, o resultado aparece em bugs conhecidos: modal de chamada tocando depois do cancelamento, botão de aceitar disponível tarde demais, tela de conexão eterna, áudio encerrado com a interface ainda ativa.
Uma máquina de estados não impede todas as falhas. Mas torna possível dizer o que deveria acontecer em cada uma delas.
Dois dispositivos podem atender a mesma chamada?
Imagine que o PING está aberto no navegador e no aplicativo desktop. Alguém liga, e o convite chega aos dois clientes.
Se ambos tentarem aceitar quase ao mesmo tempo, uma implementação ingênua pode criar duas sessões concorrentes ou deixar cada interface acreditando que venceu.
A regra definida para as chamadas individuais do PING é que apenas uma aceitação válida prevaleça. Esse não pode ser um acordo informal entre dois componentes React. Precisa ser resolvido onde exista coordenação suficiente para impedir a corrida, com um estado autoritativo para os clientes consultarem.
No caso dos canais de voz persistentes, as regras de participação entre dispositivos têm outras nuances. A lição permanece: não existe uma única semântica de “estar conectado” que sirva automaticamente para todos os contextos.
É aí que a arquitetura começa a refletir o comportamento real do produto, em vez de apenas a estrutura da interface.
Reconectar não é simplesmente tentar de novo
Uma rede pode oscilar durante a chamada. Um notebook entra em suspensão. O navegador troca de dispositivo de áudio. A sessão continua existindo do ponto de vista do serviço, mas um dos clientes precisa reconstruir sua participação.
Seria fácil chamar novamente o método de conexão e torcer para que tudo volte. Porém, em um fluxo com permissões, tokens de curta duração e criptografia de mídia, recuperar uma chamada exige respeitar uma ordem.
Primeiro é necessário descobrir se a sessão ainda é válida. Depois, recuperar as informações protegidas necessárias, obter credenciais atualizadas quando aplicável e restabelecer a mídia com as garantias exigidas. Um token expirado não deveria ser reutilizado por conveniência. E uma falha na configuração de criptografia não pode virar uma passagem silenciosa para uma chamada sem proteção.
No desenho das chamadas do PING, a premissa é falhar de forma segura: se a autorização, a troca de chaves ou a preparação da mídia protegida não puder ser concluída corretamente, não se deve reduzir silenciosamente o nível de segurança apenas para fazer a chamada conectar.
Isso tem um custo de implementação e de tratamento de erros, mas considero um custo justificável.
A mesma falha tem duas dimensões: técnica e percebida
Um exemplo que me incomodou foi a diferença entre a ação de entrar em um canal e o momento em que a interface reconhecia plenamente essa entrada. Em certos cenários, o som de ingresso chegava antes de o estado visual deixar de mostrar carregamento.
Para quem está usando, não importa se o atraso vem do handshake de mídia, de uma atualização de presença ou de uma renderização dependente de outra operação. A experiência é: “entrei ou não entrei?”.
Isso expõe uma escolha delicada. Exibir o canal cedo demais pode fazer parecer que a pessoa já está participando quando a sessão ainda não foi confirmada. Esperar todos os sinais antes de qualquer feedback cria uma interface pesada, com sensação de latência.
A saída não é maquiar o tempo com animações. É projetar feedback para os estados reais: a intenção foi registrada, a conexão está acontecendo, a participação foi confirmada. Enquanto isso, medir onde o tempo é consumido ajuda a melhorar o fluxo efetivo, e não apenas sua aparência.
Qualidade de áudio é parte do produto
Além de conectar, é preciso fazer a conversa ser confortável. O PING incorporou processamento de supressão de ruído no cliente, mas esse tipo de recurso introduz outra camada de responsabilidade: compatibilidade de dispositivos, controle de recursos, processamento em tempo real e a possibilidade de bloquear um áudio que deveria passar.
Em comunicação, um recurso tecnicamente sofisticado pode ser um retrocesso se impedir alguém de ser ouvido. Por isso, efeitos e processadores precisam ser tratados como partes testáveis da cadeia de mídia, e não como uma caixa-preta de melhoria automática.
O mesmo vale para microfone, saída de áudio, silenciamento e retorno de som. A interface deve representar o que está acontecendo no dispositivo, e não apenas o último botão que foi clicado.
A arquitetura certa é a que permite investigar o erro
Hoje, considero observabilidade e testes de cenários adversos parte central desse desenvolvimento. É importante saber se a falha aconteceu ao aceitar um convite, gerar um token, preparar a criptografia, publicar uma trilha de mídia ou atualizar a presença.
Sem essa separação, tudo vira “a chamada travou”, e a investigação começa do zero.
Também ficou claro que a qualidade de uma chamada não pode ser avaliada apenas pela taxa de conexão inicial. Precisa considerar encerramentos corretos, retomadas, inconsistências de interface, comportamento entre dispositivos e a capacidade de se recuperar sem deixar sessões fantasmas.
Ainda existem melhorias em andamento. Não apresento esse sistema como infalível; justamente o contrário. O interessante foi aprender a construir mecanismos para enxergar e reduzir as falhas que um protótipo costuma esconder.
No primeiro teste, a pergunta era “conseguimos nos ouvir?”. Agora ela é outra: conseguimos continuar confiando na chamada quando alguma coisa dá errado?
É nessa mudança de pergunta que uma funcionalidade começa a se tornar um produto.
Este texto faz parte de uma série sobre a construção do PING. No próximo, vou falar sobre como design, presença e identidade passaram a orientar a experiência.
Compartilhar em
NOTA SEMANAL / NEWSLETTER
Curtiu este insight?
Receba reflexões semanais sobre tecnologia, produto e decisões de execução.
Sem spam. Só conteúdo que vale abrir.
Notas relacionadas
03