Em que estado minha conexão está, e o que vem depois?
Em que estado minha conexão está, e o que vem depois?
Pergunta: "em que estado minha conexão está, e o que vem depois?"
Dois eixos, nunca achatados
Guest (RoomSessionStateMachine, guest.getStatus()) tem dois eixos independentes:
transport:offline→connecting→online(eretryingno meio de uma reconexão). Nada aqui é terminal —offlineé descanso, não morte.membership:unassociated→associating→ (awaiting_approvalsó quando o accessMode exige) →member→ended(terminal, único, comreason).
Host (HostTransportStateMachine, host.transport) só tem o eixo transport — não existe eixo membership no host, e portanto não existe ended nele por tipo, não só por recusa em runtime. O fim de vida do host é outra coisa: destruição do objeto via host.close() (ver receita-microfone.md), não um valor neste eixo.
Os 9 reason de ended (guest)
reason | O que aconteceu |
|---|---|
left | guest.close() — saída explícita |
room_closed | O host encerrou a sala (room.close()) |
room_expired | A sala expirou no servidor |
creator_replaced | (nunca alcançado pelo guest — ver assimetria abaixo) |
rejected | Segunda rejeição consecutiva de aprovação |
idle_timeout | Conexão ociosa sem associação, servidor fechou |
control_lost | (eixo do host — ver HostConnection#resume, não chega ao guest) |
contract_mismatch | Fingerprint do contrato divergiu do peer (mesmo nome, formas concretas diferentes) |
protocol_version_mismatch | protocolVersion do peer é diferente do seu |
Assimetria: contract_mismatch e protocol_version_mismatch terminam o guest, não o host
Não existe verbo de servidor para expulsar um guest já admitido — por isso só o guest alcança esses dois reason. O host sobrevive, na mesma sala, com o mesmo QR: um guest com contrato ou versão divergente termina sozinho (ended{reason}), e o host segue aceitando outros guests normalmente. Ver versionamento-e-deploy.md para a tabela de compatibilidade completa.
Observações não-terminais (nunca silenciadas, nunca encerram nada)
invalid_join_code, payload_too_large, bad_message, service_unavailable, occupancy_limit_not_honored e qualquer código desconhecido chegam como {code, known} pelo canal de observação (room.onObservation/equivalente do guest) — nunca terminam a sessão sozinhos, nunca são engolidos em silêncio.
Quando reconectar faz sentido vs. quando é sempre adesão nova
- Host: uma queda de transporte com sala ainda viva dispara reconexão automática e invisível (
resume_creator, usando ocreatorTokenem memória) — o app não vê nada acontecer, a menos que a retomada falhe de verdade (control_lost, sem retry). Entre salas (host sem sala aberta), o transporte tem prazo de 30s ocioso antes de cair;startRoom()depois disso reconecta de forma transparente. - Guest: não existe retomada — uma queda de transporte no meio de uma sessão de guest é sempre uma nova chamada a
joinRoom, sujeita a uma nova aprovação se o accessMode exigir.
Exibição de um único indicador
deriveDisplayStatus(status) reduz os dois eixos a um único valor para exibição (nunca fonte de verdade para lógica de controle — quem precisa dos dois eixos lê getStatus() direto).
Last updated on