diff --git a/docs/documentation/11_plugins_referencia.md b/docs/documentation/11_plugins_referencia.md index e8e09ff..538b035 100644 --- a/docs/documentation/11_plugins_referencia.md +++ b/docs/documentation/11_plugins_referencia.md @@ -38,6 +38,6 @@ Os plugins de referência são **exemplos de sala de aula**, não produtos compl | --- | --- | --- | | **chat** | texto, sala geral, unicast/multicast/TCP, TCP privado básico | imagens, moderação, histórico persistente, criptografia | | **screencast** | stream read-only, avisos de sessão | controle remoto do mouse/teclado, áudio | -| **ping** (exercício do aluno) | RTT, ping uma vez/contínuo, parar e avisar o peer | ICMP do SO, gráficos, SLA | +| **ping** (exercício do aluno) | chrome de sessão v1 (`PluginRoutingPanel`, abas ↑/↓), RTT, UDP apenas | TCP privado, ICMP do SO, gráficos, SLA | Para evoluir: copie o padrão (`Plugin` + mensagens + painel na aba) e acrescente features no **seu** JAR — sem inflar o núcleo. diff --git a/docs/documentation/17_tutorial_ping_aula.md b/docs/documentation/17_tutorial_ping_aula.md index b660415..f6014c2 100644 --- a/docs/documentation/17_tutorial_ping_aula.md +++ b/docs/documentation/17_tutorial_ping_aula.md @@ -78,19 +78,18 @@ Use `PeerIpv4` e `LocalNetworkInfo.bestLocalIpv4()` para IP legível no Windows. ## Passo 5 — `PingPanel` (UI) -`JPanel` com: +Siga o mesmo chrome do screencast: `PluginSessionWorkspace` + `PluginRoutingPanel` (`PluginKind.PING`, sem TCP privado). -- `SessionTabBar` — aba fixa **Todos** + `addTabIfAbsent` quando chega tráfego de um peer (**sem** mudar a aba ativa da shell). +- **Destino e transporte** no topo (IP, forma de envio, banner da sessão). +- Toolbar: **Enviar ping** (uma vez) e **Ping contínuo** (toggle só em abas de peer **↑**; na sala **Todos** só o envio único). +- `SessionTabBar`: sala `Todos ↑`; peers que você abre `Nome ↑`; recebimento passivo `Nome ↓` (`view:`). +- `+ Nova` / `PeerDraftPanel` para IP manual. - `JTextArea` monoespaçada por aba; linhas como `[HH:mm:ss] pong ← Alice · RTT 42 ms`. -- Botão **Parar todos os pings contínuos** chamando o controller. +- Abas **↓**: `bindReceiveSession` — controles de envio desabilitados. -**Não** use `JFrame`. No `PingPlugin`: +**Não** use `JFrame`. No `PingPlugin`: `bindShellWorkspaceContent(panel)`. -```java -bindShellWorkspaceContent(panel); -``` - -A aba só abre quando o usuário clicar na galeria **Plugins** ou numa peer action. +A aba da shell só abre quando o usuário clicar na galeria **Plugins** ou numa peer action (sem enviar ping automaticamente). ## Passo 6 — `PingPlugin` @@ -107,14 +106,12 @@ A aba só abre quando o usuário clicar na galeria **Plugins** ou numa peer acti **Peer actions sugeridas:** -| id | Label | Alvo | -| --- | --- | --- | -| `ping.once` | Ping uma vez | um peer | -| `ping.continuous` | Ping contínuo | um peer | -| `ping.stop` | Parar ping | um peer | -| `ping.all.once` | Ping para todos (uma vez) | Todos → `MULTICAST_UDP` | +| id | Label | Alvo | Comportamento | +| --- | --- | --- | --- | +| `ping.peer` | Enviar ping para esta pessoa | um peer | Abre/foca o plugin e a aba `↑` com o IP — **sem** disparar ping | +| `ping.room` | Abrir ping na sala (Todos) | Todos | Abre a aba sala — **sem** disparar ping | -Em cada ação de peer único: `workspace.openOrFocusTab(getIdentifier(), getDisplayName())` e chame o controller. +O envio fica nos botões do painel. `receiveMessage`: despache para o controller com `SwingUtilities.invokeLater`. @@ -126,8 +123,8 @@ Em cada ação de peer único: `workspace.openOrFocusTab(getIdentifier(), getDis 2. Aba **Configurações** → **Instalar JAR…** (ou copie para `~/pitiupi/plugins/`). 3. **Reinicie** o Pitiupi (obrigatório após mudar plugins). 4. Dois processos no mesmo PC: portas **5000** e **5001**, nomes diferentes. -5. Peer action **Ping uma vez** → veja RTT no log. -6. **Ping contínuo** → linhas a cada ~1 s; **Parar ping** → o outro vê “parou o ping contínuo”. +5. Lista lateral → **Enviar ping para esta pessoa** → aba `↑` com IP; clique **Enviar ping** → RTT no log. +6. Toggle **Ping contínuo** na aba `↑` → linhas a cada ~1 s; desligar o toggle → o outro vê “parou o ping contínuo” na aba `↓`. 7. Com colega na LAN: mesma porta, JAR instalado nos dois. Instalação usa o mesmo `PluginStore` da aba **Configurações** (`installFromFile` + reinício). O núcleo expõe `pitiupi.tools.PluginStoreCli` para testes sem interface gráfica. @@ -141,7 +138,7 @@ O chat usa a mesma ideia de abas de sessão, mas adiciona roteamento TCP privado - [ ] SPI e `getIdentifier` únicos - [ ] Três mensagens registradas - [ ] RTT calculado no `Pong` -- [ ] Aba passiva ao receber ping de peer novo +- [ ] Aba passiva `↓` ao receber ping de peer novo (sem roubar foco da shell) - [ ] Contínuo + parar com aviso ao peer - [ ] Reinício após instalar JAR - [ ] Teste com segundo usuário (5001 ou outro PC) diff --git a/pitiupi/src/pitiupi/application/messaging/PluginTransportCatalog.java b/pitiupi/src/pitiupi/application/messaging/PluginTransportCatalog.java index ad34c85..3ff90cb 100644 --- a/pitiupi/src/pitiupi/application/messaging/PluginTransportCatalog.java +++ b/pitiupi/src/pitiupi/application/messaging/PluginTransportCatalog.java @@ -9,7 +9,8 @@ public final class PluginTransportCatalog { public enum PluginKind { CHAT, - SCREEN_CAST + SCREEN_CAST, + PING } private PluginTransportCatalog() { @@ -22,7 +23,7 @@ public final class PluginTransportCatalog { TransportMode.UNICAST_UDP, TransportMode.TCP ); - case SCREEN_CAST -> List.of( + case SCREEN_CAST, PING -> List.of( TransportMode.MULTICAST_UDP, TransportMode.UNICAST_UDP ); @@ -35,6 +36,7 @@ public final class PluginTransportCatalog { TransportMode.UNICAST_UDP, TransportMode.TCP ); + case PING -> List.of(TransportMode.UNICAST_UDP); }; } } diff --git a/pitiupi/test/pitiupi/application/messaging/PluginTransportCatalogTest.java b/pitiupi/test/pitiupi/application/messaging/PluginTransportCatalogTest.java index b2ce28a..a2454ea 100644 --- a/pitiupi/test/pitiupi/application/messaging/PluginTransportCatalogTest.java +++ b/pitiupi/test/pitiupi/application/messaging/PluginTransportCatalogTest.java @@ -13,4 +13,18 @@ class PluginTransportCatalogTest { assertTrue(modes.contains(TransportMode.MULTICAST_UDP)); assertFalse(modes.contains(TransportMode.TCP)); } + + @Test + void pingBroadcastExcludesTcp() { + var modes = PluginTransportCatalog.forBroadcast(PluginTransportCatalog.PluginKind.PING); + assertTrue(modes.contains(TransportMode.MULTICAST_UDP)); + assertFalse(modes.contains(TransportMode.TCP)); + } + + @Test + void pingSinglePeerIsUdpOnly() { + var modes = PluginTransportCatalog.forSinglePeer(PluginTransportCatalog.PluginKind.PING); + assertTrue(modes.contains(TransportMode.UNICAST_UDP)); + assertFalse(modes.contains(TransportMode.TCP)); + } }