Pular para o conteúdo

JHONATAN OLIVEIRA®

PORTFOLIO / 2026

FRONTEND / PRODUTO / DESIGN

Engenharia, direção e ofício digital em um único sistema contínuo.

ISSUE / 01

Voltar ao journal

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

#PING#LiveKit#WebRTC#confiabilidade#criptografia

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