Índices por jornada, convenções, diagramas Mermaid, correções de arquitetura (MainShellFrame, TCP/PluginManager), tutoriais com verificações e troubleshooting; remove redirect pitiupi/docs. Co-authored-by: Cursor <cursoragent@cursor.com>
5.0 KiB
Comunicação UDP
Teoria: UDP envia datagramas sem conexão; multicast replica um pacote na LAN para todos os membros do grupo. No Pitiupi: presença e muitas mensagens de plugins usam o mesmo MulticastSocket na porta do login. Limitação: sem garantia de entrega nem ordem — plugins com imagens grandes devem considerar perda e MTU.
A classe SocketUDP é responsável pela comunicação UDP da aplicação.
Ela utiliza um MulticastSocket associado à porta configurada pela aplicação e
ingressa no grupo multicast 224.0.0.3. Por ser baseada em UDP, a comunicação não
estabelece uma conexão permanente entre os peers.
A classe estende Thread, mantendo um processo contínuo de recepção de datagramas
enquanto a aplicação está em execução.
O SocketUDP suporta dois modos de envio:
- multicast, destinado ao grupo de peers
- unicast, destinado diretamente ao endereço IP de um peer específico
Inicialização
Durante sua inicialização, o SocketUDP:
- obtém o endereço do grupo multicast;
- cria um
MulticastSocketna porta escolhida no login (mesma porta TCP da sala); - configura os buffers de envio e recepção;
- habilita o reuso do endereço;
- ingressa no grupo multicast.
O tamanho dos buffers de comunicação é configurado para 256000 bytes.
Envio de mensagens UDP
O SocketUDP suporta dois modos de envio de mensagens: multicast e unicast, ambos
baseados no mesmo mecanismo interno de criação e envio de DatagramPacket.
O método sendMulticast() envia uma mensagem para o grupo multicast da aplicação.
Nesse caso, o DatagramPacket é direcionado ao endereço multicast configurado,
permitindo que todas as instâncias participantes do grupo recebam a mensagem
simultaneamente.
Já o método sendUnicast() permite enviar uma mensagem diretamente para um peer
específico. Nesse caso, o DatagramPacket é direcionado ao endereço IP informado pelo
chamador, mantendo a mesma porta utilizada pela aplicação.
Ambos os métodos são, na prática, abstrações de um único mecanismo interno de envio,
que utiliza o mesmo processo de criação e envio de DatagramPacket por baixo dos
panos. A diferença entre eles está apenas no endereço de destino: enquanto o multicast
utiliza o grupo compartilhado, o unicast direciona o pacote a um IP específico.
Recepção de mensagens
O método receive() mantém um loop aguardando novos datagramas.
Ao receber uma mensagem, o SocketUDP inicialmente tenta identificar se os dados
correspondem a uma HeartbeatMessage.
O processamento segue o seguinte fluxo:
- O datagrama é recebido pelo
MulticastSocket. - Os dados recebidos são analisados pelo método
tryParseHeartbeat(). - Caso seja identificada uma
HeartbeatMessage, ela é encaminhada aoHeartbeatManager, juntamente com o endereço IP de origem. - Caso não seja um heartbeat, a mensagem é encaminhada para todos os plugins carregados.
- Cada plugin decide se a mensagem recebida pertence à sua funcionalidade.
Essa separação mantém as mensagens de infraestrutura, como heartbeat, sob responsabilidade do núcleo da aplicação, enquanto as mensagens específicas das funcionalidades são processadas pelos plugins.
Identificação de mensagens de heartbeat
O método tryParseHeartbeat() tenta desserializar os dados recebidos e verificar se o
objeto resultante é uma instância de HeartbeatMessage.
Caso a mensagem não possa ser desserializada ou não corresponda ao tipo esperado, o
método retorna null. Nesse caso, a mensagem é tratada como uma mensagem destinada aos
plugins.
Encerramento
O método close() interrompe a execução do processo de recepção, remove a aplicação
do grupo multicast e fecha o MulticastSocket.
A variável running é utilizada para sinalizar que o processo de recepção deve ser
encerrado.
Interface de rede
LocalNetworkInfo.preferredNetworkInterface() escolhe a interface para o multicast: Ethernet antes de Wi‑Fi; em cabo APIPA (169.254.*) prioriza esse endereço. Em sala só Wi‑Fi, a interface wireless é usada normalmente. Requisito: peers na mesma sub-rede e multicast permitido — ver appendix_portas_e_multicast.md.
Sequência didática (plugin → peer B)
sequenceDiagram
participant UI as Plugin_UI
participant Disp as MessageDispatcher
participant CM as ConnectionManager
participant UDP as SocketUDP
participant LAN as LAN_UDP
participant UDPb as SocketUDP_peerB
participant PM as PluginManager_peerB
UI->>Disp: enviar Message + modo + destino
Disp->>CM: send UDP
CM->>UDP: sendUnicast ou sendMulticast
UDP->>LAN: DatagramPacket
LAN->>UDPb: receive
UDPb->>PM: byte[] desserializado
PM->>UI: receiveMessage no plugin
Falhas comuns: firewall bloqueando UDP na porta do login; portas diferentes entre peers; isolamento de clientes no Wi‑Fi; WSL num lado e Windows nativo no outro.