feat(rede): nome, porta, saída e TTL em tempo real
A sala acompanha a interface escolhida, o TCP deixa de travar a janela e a aba de um peer continua fechável quando o IP muda. O guia do colega usa os saltos do traceroute como TTL mínimo. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
baaf7582d3
commit
22540eaffb
31 files changed
+1194
-110
No files matched your search
+2
-2
@@ -17,14 +17,14 @@ Convenções editoriais: [documentation/00_convencoes.md](documentation/00_conve
|
||||
| Leitor | Trilha |
|
||||
| --- | --- |
|
||||
| **Primeiro uso** | [00_quickstart](documentation/00_quickstart.md) → [09_sistema_de_plugins](documentation/09_sistema_de_plugins.md) → [10_tutorial_plugin](documentation/10_tutorial_plugin.md) → [11_plugins_referencia](documentation/11_plugins_referencia.md) |
|
||||
| **Redes (conceito + código)** | [16_fundamentacao_redes](documentation/16_fundamentacao_redes.md) → [05](documentation/05_udp_multicast.md)–[08](documentation/08_heartbeat_e_presenca.md) → [appendix_portas_e_multicast](documentation/appendix_portas_e_multicast.md) |
|
||||
| **Redes (conceito + código)** | [16_fundamentacao_redes](documentation/16_fundamentacao_redes.md) → [05](documentation/05_udp_multicast.md)–[08](documentation/08_heartbeat_e_presenca.md) → [appendix_portas_e_multicast](documentation/appendix_portas_e_multicast.md) → [17_teste_com_colega](documentation/17_teste_com_colega.md) |
|
||||
| **Desenvolvedor núcleo** | [13_guia_desenvolvimento](documentation/13_guia_desenvolvimento.md) → [14_arquitetura_e_manutencao](documentation/14_arquitetura_e_manutencao.md) → [04_inicializacao_e_gui](documentation/04_inicializacao_e_gui.md) |
|
||||
|
||||
## Manutenção rápida
|
||||
|
||||
| Mudança | Onde documentar |
|
||||
| --- | --- |
|
||||
| UDP/TCP, multicast, portas | 05, 06, appendix |
|
||||
| UDP/TCP, multicast, portas | 05, 06, appendix, 17 |
|
||||
| SPI / plugins | 09, 10 |
|
||||
| Decisão de arquitetura | decision-register |
|
||||
| Débito técnico | engineering_backlog |
|
||||
@@ -22,5 +22,10 @@
|
||||
| D22 | `PeerIpv4` para IP de peer na UI | No Windows, `InetAddress.getHostAddress()` pode devolver IPv6-mapeado e sufixo de zona (`%n`); chat e roteamento usam IPv4 pontilhado | [appendix_portas_e_multicast.md](documentation/appendix_portas_e_multicast.md) |
|
||||
| D23 | Foco de atividade e badges | **Adiado na v1** — núcleo (`PeerActivityFocus` / `PeerActivityInbox`) mantido; UI sem badges; recebimento passivo em sub-abas (`addTabIfAbsent`) | [09_sistema_de_plugins.md](documentation/09_sistema_de_plugins.md) |
|
||||
| D24 | Avisos de sessão (`SessionNoticeMessage`) | Início/fim de atividades (ex. `screen_cast` END ao parar share); extensível por plugin/canal | [09_sistema_de_plugins.md](documentation/09_sistema_de_plugins.md) |
|
||||
| D25 | Nome novo no heartbeat já existente | A lista do colega atualiza o `User` quando o `userName` muda | [08_heartbeat_e_presenca.md](documentation/08_heartbeat_e_presenca.md) |
|
||||
| D26 | Troca de porta sai da sala | Goodbye na porta antiga, lista local zerada, anúncio na porta nova | [appendix_portas_e_multicast.md](documentation/appendix_portas_e_multicast.md) |
|
||||
| D27 | TTL padrão 1, ajustável de 1 a 32 | 1 permanece na sub-rede local; valor maior é opção de configuração | [appendix_portas_e_multicast.md](documentation/appendix_portas_e_multicast.md) |
|
||||
| D28 | Saída Automático, Cabo ou Wi-Fi | Multicast, IP exibido e TCP de saída usam a interface escolhida | [appendix_portas_e_multicast.md](documentation/appendix_portas_e_multicast.md) |
|
||||
| D29 | Connect TCP com prazo de 5 s fora da EDT | Aviso só enquanto não há socket aberto para aquele IP | [06_tcp_conexoes.md](documentation/06_tcp_conexoes.md) |
|
||||
|
||||
Novas decisões: adicionar linha nesta tabela e detalhar no arquivo técnico correspondente.
|
||||
@@ -67,20 +67,20 @@ A interface gráfica é Swing, organizada em shell (`pitiupi.presentation.shell`
|
||||
|
||||
Plugins expõem `getName()` (técnico), `getIdentifier()` (SPI) e `getDisplayName()` (texto na galeria e nas abas).
|
||||
|
||||
A aba **Configurações** mostra em cima **Sua conexão** (nome, porta, IP local, ID da instância, contagem de peers; campos selecionáveis para copiar manualmente) e embaixo a tabela de JARs instalados (altura reduzida).
|
||||
A aba **Configurações** mostra em cima **Sua conexão**: nome e porta editáveis, saída (Automático, Cabo ou Wi-Fi), TTL, IP local, interface em uso, ID da instância e contagem de peers. **Aplicar** grava a preferência e, se porta, saída ou TTL mudaram, reabre a rede na hora. IP e ID continuam somente leitura. Embaixo fica a tabela de JARs instalados.
|
||||
|
||||
Durante a inicialização, cada plugin recebe `ConnectionManager` e `PluginWorkspace`
|
||||
no método `createPlugin()`. Menus multicast na barra superior não são mais usados;
|
||||
ações para todos os peers migram para **peer actions** (contexto na lista lateral).
|
||||
Ao iniciar, só as abas **Plugins** e **Configurações** ficam visíveis. Cada plugin registra um painel com `bindShellWorkspaceContent`; a aba abre ao clicar na galeria ou via peer action. Referência: **Conversa na rede** (`ChatPanel`) e **Compartilhar tela** (`ScreenCastPanel`).
|
||||
|
||||
O **chat** usa campo de mensagem compacto (~2 linhas, quebra de linha; barra de rolagem vertical só se o texto não couber). O histórico ocupa a maior parte da altura da aba (divisor proporcional ao abrir a janela).
|
||||
O **chat** usa campo de mensagem compacto (~2 linhas, quebra de linha; barra de rolagem vertical só se o texto não couber). O histórico ocupa a maior parte da altura da aba (divisor proporcional ao abrir a janela). Cada pessoa tem uma sub-aba; o × fecha essa sub-aba mesmo com outras ao lado. Se a pessoa muda de cabo para Wi-Fi, a sub-aba já aberta passa a usar o IP novo em vez de aparecer uma segunda vez com o mesmo nome.
|
||||
|
||||
Canal TCP privado do chat fica no mesmo `ChatPanel` (histórico separado por conversa: sala geral, peer por IP, privado com toggle). O núcleo mantém `PeerActivityInbox` para atividade por peer; indicadores visuais completos na lista lateral ainda não fazem parte da v1 (**D23**).
|
||||
|
||||
Ao fechar a aba superior de **Compartilhar tela** (×), o núcleo chama `Plugin.onShellTabClosed()` — o plugin interrompe captura e envio (toggle desligado). Reabrir pela galeria deve mostrar compartilhamento inativo.
|
||||
|
||||
**TCP (transporte)** envia uma mensagem serializada pelo núcleo (`sendTcp`), na porta do login. **TCP privado** (toggle) abre conexão dedicada ao plugin entre dois peers; com o toggle ativo, o combo de transporte fica desabilitado e o envio usa esse canal. Na UI só se informa o **IP** do peer: UDP/TCP unicast do Pitiupi usa sempre a **mesma porta** que você escolheu no login (convenção de sala: todos com a mesma porta, ex. 5000 e 5001 em testes no mesmo PC).
|
||||
**TCP (transporte)** envia uma mensagem serializada pelo núcleo, na porta desta instância. A primeira conexão com um IP que ainda não tem socket aberto corre fora da thread da janela: o chat mostra “Conectando em …”, espera no máximo cerca de 5 s e, se falhar, avisa uma vez. Mensagens seguintes no mesmo socket não repetem esse aviso. **TCP privado** (toggle) abre conexão dedicada ao plugin entre dois peers, com o mesmo aviso só na abertura. Na UI só se informa o **IP** do peer: UDP/TCP unicast do Pitiupi usa sempre a **mesma porta** desta instância (convenção de sala: todos com a mesma porta, ex. 5000 e 5001 em testes no mesmo PC).
|
||||
|
||||
Textos da UI (destino, combo de forma de envio e linha **“Como esta mensagem vai”**) usam linguagem simples e o termo técnico entre parênteses (multicast UDP, UDP unicast, TCP). Na sala, o transporte não é só multicast: o combo pode escolher cópias unicast ou TCP para cada pessoa, conforme o plugin.
|
||||
|
||||
|
||||
@@ -24,7 +24,8 @@ Durante sua inicialização, o `SocketUDP`:
|
||||
2. cria um `MulticastSocket` na **porta escolhida no login** (mesma porta TCP da sala);
|
||||
3. configura os buffers de envio e recepção;
|
||||
4. habilita o reuso do endereço;
|
||||
5. ingressa no grupo multicast.
|
||||
5. define o TTL (padrão **1**, alterável na aba Configurações) e a interface de saída;
|
||||
6. ingressa no grupo multicast.
|
||||
|
||||
O tamanho dos buffers de comunicação é configurado para `256000` bytes.
|
||||
|
||||
|
||||
@@ -10,6 +10,10 @@ múltiplas mensagens.
|
||||
|
||||
A arquitetura utiliza uma conexão TCP persistente por endereço de peer.
|
||||
|
||||
**Teoria:** `connect` sem prazo pode ficar parado até o sistema operacional desistir. **No Pitiupi:** `ConnectionFactory` usa `Socket.connect` com prazo de **5 s** (`CONNECT_TIMEOUT_MS`). O chat dispara essa abertura numa thread do núcleo (`sendTcpAsync` / `connectPluginTcpAsync`) e só mostra “Conectando em …” quando ainda não existe socket aberto para aquele IP. **Limitação:** o prazo não é configurável na tela; o timeout de leitura depois do handshake continua longo (minutos).
|
||||
|
||||
Ao mudar porta, saída ou TTL, o `ConnectionManager` envia goodbye, fecha as TCP locais e reabre o `ServerSocket`. Se a porta nova não abre, a sala anterior é restaurada.
|
||||
|
||||
O `TcpConnectionManager` mantém um mapa `InetAddress` → `TcpConnection`, permitindo reutilizar a mesma conexão para vários envios ao mesmo peer.
|
||||
|
||||
### SocketTCP
|
||||
|
||||
@@ -72,7 +72,13 @@ Lista de peers ativos
|
||||
| Timeout de ausência | ~15 s | Peer some após queda ou fechamento sem goodbye |
|
||||
| Goodbye | multicast ao sair | Remove peer mais rápido que só timeout |
|
||||
|
||||
Em **Wi‑Fi de laboratório**, heartbeat usa o mesmo multicast que o chat na sala geral — mesma porta no login, mesma sub-rede, sem isolamento AP→AP. Ver [appendix_portas_e_multicast.md](appendix_portas_e_multicast.md).
|
||||
Em **Wi‑Fi de laboratório**, heartbeat usa o mesmo multicast que o chat na sala geral — mesma porta, mesma sub-rede, sem isolamento AP→AP. Ver [appendix_portas_e_multicast.md](appendix_portas_e_multicast.md) e [17_teste_com_colega.md](17_teste_com_colega.md).
|
||||
|
||||
### Nome e troca de sala
|
||||
|
||||
O nome vai dentro do `HeartbeatMessage` que já existe. Se o nome mudar, o receptor atualiza o peer na lista e avisa a interface; não há outra mensagem só para isso.
|
||||
|
||||
Trocar a porta (ou a saída, ou o TTL) envia `GoodbyeMessage` na sala atual, esvazia a lista local e anuncia de imediato depois do novo socket. Quem ficou na porta antiga deixa de ver esta instância. Quem já está na porta nova aparece no anúncio seguinte. Se o goodbye se perder, o timeout de cerca de 15 s ainda remove o peer.
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
# Teste com um colega
|
||||
|
||||
**Teoria:** dois processos só se descobrem se compartilham a mesma sub-rede, a mesma porta de aplicação e um caminho em que o multicast da LAN não seja filtrado. **No Pitiupi:** a lista **Usuários nesta rede** enche com heartbeats UDP. **Limitação:** o Pitiupi não executa `ping` nem `traceroute` do sistema; esses comandos servem para separar problema de rede de problema do aplicativo.
|
||||
|
||||
Os dois Pitiupi precisam usar a **mesma porta** (na sala, em geral **5000**). Portas diferentes são salas diferentes: quem está em 5001 não aparece para quem ficou em 5000.
|
||||
|
||||
## O que conferir na aplicação
|
||||
|
||||
Abra a aba **Configurações**, seção **Sua conexão**:
|
||||
|
||||
- **IP local** e o nome da **interface** (por exemplo `eth0 · 192.168.0.15`).
|
||||
- **Porta** em que esta instância escuta UDP e TCP.
|
||||
- **Saída:** Automático, Cabo ou Wi-Fi. Os dois colegas precisam estar na mesma rede dessa interface.
|
||||
- **TTL:** o padrão é **1**. O número de saltos do `tracert` (ou `traceroute`) até o IP do colega é o mínimo a colocar aqui. Se a linha 1 já é o IP dele, use **1**. Cada roteador no meio soma 1, até o máximo **32**. O teste na mesma sub-rede usa 1.
|
||||
|
||||
O nome na rede também se altera aí. O colega passa a ver o nome novo no próximo anúncio (até cerca de 5 s), sem você sair e voltar da lista.
|
||||
|
||||
## O que conferir no sistema
|
||||
|
||||
Substitua `5000` e o IP do colega pelos valores da aba Configurações.
|
||||
|
||||
### Windows
|
||||
|
||||
- IP: `ipconfig` e o IPv4 do adaptador Ethernet ou Wi-Fi.
|
||||
- Porta em escuta: `netstat -ano | findstr :5000`
|
||||
- Alcance: `ping` no IP do colega.
|
||||
- Caminho: `tracert` no IP do colega. Conte as linhas numeradas até o IP dele: esse número é o TTL mínimo na aba Configurações.
|
||||
- Porta TCP do aplicativo: no PowerShell, `Test-NetConnection -ComputerName IP -Port 5000`
|
||||
|
||||
### Linux
|
||||
|
||||
- IP: `ip -4 addr`
|
||||
- Porta em escuta: `ss -lntu | grep 5000`
|
||||
- Alcance: `ping -c 3 IP`
|
||||
- Caminho: `traceroute IP` ou `tracepath IP`. Conte os saltos até o IP do colega: esse número é o TTL mínimo.
|
||||
- Porta TCP do aplicativo: `nc -vz -w 3 IP 5000` (ou `ncat`)
|
||||
|
||||
## Como ler o resultado
|
||||
|
||||
- **O ping falha.** O problema está na rede entre os PCs: sub-rede diferente, cabo, Wi-Fi ou isolamento de clientes no roteador. O Pitiupi não contorna isso.
|
||||
- **O ping funciona e a porta TCP não abre.** Firewall, porta errada ou o outro Pitiupi não está escutando. Confira a porta na aba Configurações e libere UDP e TCP nessa porta.
|
||||
- **O ping com TTL 1 responde e a lista só mostra Todos.** A descoberta é multicast, e um TTL baixo não é a causa quando o `tracert` tem um salto só. Confira porta igual, a mesma saída (os dois no cabo ou os dois no Wi-Fi; `169.254` e `192.168` ao mesmo tempo não se veem), firewall de UDP e isolamento de clientes. Um lado no WSL e o outro no Windows costuma impedir o multicast: os dois peers precisam estar no mesmo tipo de ambiente.
|
||||
- **O `tracert` tem mais de um salto e a lista fica vazia.** Suba o TTL em Configurações até o número de saltos (máximo 32) e aplique nos dois. Um roteador no meio só entrega o multicast se estiver disposto a encaminhar o grupo.
|
||||
- **O colega está na lista e o TCP avisa que não conectou.** A tentativa de abrir o socket espera no máximo cerca de **5 s** e a janela continua utilizável. Veja firewall de TCP ou se a porta mudou no meio do caminho.
|
||||
|
||||
A lista espera cerca de **5 s** entre anúncios e remove quem fica cerca de **15 s** sem heartbeat. Ao trocar de porta, esta instância envia goodbye na sala antiga e passa a anunciar na porta nova.
|
||||
|
||||
Detalhe de portas, interface e TTL: [appendix_portas_e_multicast.md](appendix_portas_e_multicast.md).
|
||||
@@ -8,7 +8,7 @@
|
||||
| --- | --- |
|
||||
| **Início** | [00_quickstart](00_quickstart.md), [02_modulos](02_modulos_do_repositorio.md), [03_build](03_build_ant_netbeans.md) |
|
||||
| **Arquitetura e GUI** | [04_inicializacao_e_gui](04_inicializacao_e_gui.md), [13_guia_desenvolvimento](13_guia_desenvolvimento.md), [14_arquitetura_e_manutencao](14_arquitetura_e_manutencao.md) |
|
||||
| **Rede** | [05_udp_multicast](05_udp_multicast.md), [06_tcp_conexoes](06_tcp_conexoes.md), [07_mensagens](07_mensagens_e_serializacao.md), [08_heartbeat](08_heartbeat_e_presenca.md), [16_fundamentacao_redes](16_fundamentacao_redes.md), [appendix_portas_e_multicast](appendix_portas_e_multicast.md) |
|
||||
| **Rede** | [05_udp_multicast](05_udp_multicast.md), [06_tcp_conexoes](06_tcp_conexoes.md), [07_mensagens](07_mensagens_e_serializacao.md), [08_heartbeat](08_heartbeat_e_presenca.md), [16_fundamentacao_redes](16_fundamentacao_redes.md), [17_teste_com_colega](17_teste_com_colega.md), [appendix_portas_e_multicast](appendix_portas_e_multicast.md) |
|
||||
| **Plugins** | [09_sistema_de_plugins](09_sistema_de_plugins.md), [10_tutorial_plugin](10_tutorial_plugin.md), [11_plugins_referencia](11_plugins_referencia.md), [12_transporte_e_peer_actions](12_menus_unicast_multicast.md) |
|
||||
| **Qualidade** | [15_testes_e_gate](15_testes_e_gate.md), [engineering_backlog](engineering_backlog.md) |
|
||||
|
||||
@@ -23,4 +23,5 @@
|
||||
| 9–12 | 09–12 | Plugins, tutorial genérico, transporte na UI |
|
||||
| 13–15 | 13–15 | Dev, manutenção, testes |
|
||||
| 16 | [16_fundamentacao_redes.md](16_fundamentacao_redes.md) | Fundamentação redes ↔ código |
|
||||
| 17 | [17_teste_com_colega.md](17_teste_com_colega.md) | IP, porta, ping e lista entre dois PCs |
|
||||
| — | [appendix_portas_e_multicast.md](appendix_portas_e_multicast.md) | Portas, Wi‑Fi, WSL |
|
||||
@@ -2,9 +2,11 @@
|
||||
|
||||
## Configuração
|
||||
|
||||
- **Nome** e **porta** definidos no diálogo de login (`Login`).
|
||||
- A mesma porta é usada para UDP (multicast socket) e TCP (`ServerSocket`).
|
||||
- Preferências persistidas localmente (`java.util.prefs`).
|
||||
- **Nome** e **porta** começam no diálogo de login e podem ser alterados na aba **Configurações** sem reiniciar. A alteração vale na hora.
|
||||
- A mesma porta é usada para UDP (multicast socket) e TCP (`ServerSocket`). Trocar a porta sai da sala antiga (goodbye) e passa a procurar colegas na porta nova.
|
||||
- **Saída:** Automático (cabo antes de Wi-Fi), só Cabo ou só Wi-Fi. O multicast e o IP exibido seguem essa escolha. O TCP de saída também sai pelo IPv4 dessa interface.
|
||||
- **TTL** do multicast: padrão **1** (só a rede local). Na Configurações, de 1 a 32.
|
||||
- Preferências persistidas localmente (`java.util.prefs`): nome, porta, TTL e saída. `config.properties` não guarda esses campos.
|
||||
|
||||
## Multicast
|
||||
|
||||
@@ -31,7 +33,9 @@ Executar o Pitiupi no WSL e peers no Windows (ou vice-versa) pode falhar em mult
|
||||
|
||||
## Escolha de interface (multicast)
|
||||
|
||||
O núcleo associa o socket multicast à interface de rede preferida: **cabo (Ethernet) antes de Wi‑Fi**; em cabo com link-local APIPA, prioriza IPv4 **`169.254.*`**. Isso não substitui a exigência de **mesma sub-rede** entre os dois PCs — `169.254.x` e `192.168.x` ao mesmo tempo em hosts diferentes não compartilham heartbeat.
|
||||
No modo **Automático**, o núcleo associa o socket multicast à interface preferida: **cabo (Ethernet) antes de Wi‑Fi**; em cabo com link-local APIPA, prioriza IPv4 **`169.254.*`**. **Cabo** ou **Wi-Fi** na aba Configurações restringe a essa família (nome da interface ou rótulo `Ethernet` / `Wi-Fi`). Isso não substitui a exigência de **mesma sub-rede** entre os dois PCs — `169.254.x` e `192.168.x` ao mesmo tempo em hosts diferentes não compartilham heartbeat.
|
||||
|
||||
Roteiro para achar o próprio IP, a porta e o motivo de a lista ficar vazia: [17_teste_com_colega.md](17_teste_com_colega.md).
|
||||
|
||||
## IP do peer na UI (Windows)
|
||||
|
||||
@@ -51,4 +55,4 @@ Ao abrir conversa pela lista de presença, o campo de destino usa **`PeerIpv4`**
|
||||
| --- | --- |
|
||||
| Lista só com **Todos**, sem peers | Porta igual? Mesma sub-rede? Firewall UDP? AP isolation? WSL num dos PCs? |
|
||||
| Plugin não recebe | Desserialização / SPI / JAR em `PITIUPI_HOME/plugins` |
|
||||
| TCP falha | Peer visível na lista? IP correto? |
|
||||
| TCP falha | Peer visível na lista? IP correto? A tentativa avisa em cerca de 5 s e não trava a janela |
|
||||
Reference in new issue
Block a user