Documentação de funções e arquivo Documentação.md
This commit is contained in:
parent
5d650df8eb
commit
cf43f62793
|
|
@ -0,0 +1,208 @@
|
|||
# Arquitetura da aplicação
|
||||
|
||||
## Visão geral
|
||||
|
||||
O Share My Sheet é uma plataforma P2P baseada em uma arquitetura de plugins,
|
||||
desenvolvida para permitir a criação de aplicações distribuídas sobre uma
|
||||
infraestrutura comum de comunicação em rede.
|
||||
|
||||
A aplicação fornece mecanismos de descoberta de usuários, comunicação
|
||||
multicast, troca de mensagens serializadas e integração de extensões por meio
|
||||
de plugins. Dessa forma, novos comportamentos podem ser adicionados sem
|
||||
modificar o núcleo da aplicação.
|
||||
|
||||
O projeto foi desenvolvido como suporte às práticas da disciplina de Redes de
|
||||
Computadores, servindo também como base para experimentação de aplicações
|
||||
distribuídas e desenvolvimento de projetos acadêmicos.
|
||||
|
||||
## Arquitetura geral
|
||||
|
||||
A aplicação é dividida em três grupos principais:
|
||||
|
||||
- **Núcleo da aplicação**: A `MainWindow` atua como ponto central da aplicação,
|
||||
sendo responsável por inicializar e integrar esses componentes durante a
|
||||
execução.
|
||||
- **Sistema de plugins**: responsável por adicionar funcionalidades sem
|
||||
alterar o núcleo.
|
||||
- **Comunicação de rede**: responsável pela troca de mensagens entre
|
||||
instâncias da aplicação.
|
||||
|
||||
## Inicialização da aplicação
|
||||
|
||||
1. A MainWindow é criada.
|
||||
2. O Socket é inicializado e inicia a comunicação multicast.
|
||||
3. O HeartbeatManager é criado e inicia o envio periódico de heartbeats.
|
||||
4. O painel de usuários online é registrado como listener do HeartbeatManager.
|
||||
5. O PluginLoader procura e carrega os plugins disponíveis.
|
||||
|
||||
## Sistema de comunicação
|
||||
|
||||
### Socket
|
||||
|
||||
A classe `Socket` é responsável pela comunicação de rede da aplicação.
|
||||
Ela utiliza comunicação multicast UDP para permitir que diferentes
|
||||
instâncias da aplicação troquem mensagens sem a necessidade de um servidor
|
||||
central.
|
||||
|
||||
A classe estende `Thread`, pois mantém um processo contínuo de recepção de
|
||||
mensagens enquanto a aplicação continua executando suas demais atividades.
|
||||
|
||||
Durante sua inicialização, o socket:
|
||||
- obtém o endereço do grupo multicast;
|
||||
- cria um `MulticastSocket` utilizando a porta configurada;
|
||||
- configura os buffers de comunicação;
|
||||
- entra no grupo multicast.
|
||||
|
||||
#### Envio de mensagens
|
||||
|
||||
O método `send()` recebe uma mensagem já serializada em bytes e cria um
|
||||
`DatagramPacket`, enviando-o para o grupo multicast.
|
||||
|
||||
De forma geral, o socket atua apenas como mecanismo de transporte das mensagens.
|
||||
A única exceção é o tratamento de HeartbeatMessage, utilizado pela infraestrutura
|
||||
da aplicação para manter a lista de usuários ativos.
|
||||
|
||||
#### Recepção de mensagens
|
||||
|
||||
O método `receive()` mantém um loop aguardando novas mensagens multicast.
|
||||
|
||||
Ao receber uma mensagem:
|
||||
1. Os dados são analisados para verificar se correspondem a um
|
||||
`HeartbeatMessage`.
|
||||
2. Caso seja um heartbeat, a mensagem é encaminhada ao `HeartbeatManager`
|
||||
para atualização dos usuários ativos.
|
||||
3. Caso contrário, a mensagem é enviada para todos os plugins carregados
|
||||
através do método `receiveMessage()`.
|
||||
|
||||
Esse comportamento permite que a aplicação principal trate mensagens de
|
||||
infraestrutura (como heartbeat), enquanto mensagens específicas de plugins
|
||||
são processadas pelas extensões correspondentes.
|
||||
|
||||
### Message
|
||||
|
||||
A classe `Message` representa a estrutura base das mensagens trocadas pela
|
||||
aplicação.
|
||||
|
||||
Todas as mensagens utilizadas pelo sistema devem herdar dessa classe. Ela
|
||||
implementa `Serializable`, permitindo que objetos de mensagem sejam
|
||||
convertidos em vetores de bytes para transmissão pela rede.
|
||||
|
||||
A serialização é realizada pelo método `toByteArray()`, que transforma uma
|
||||
instância da mensagem em uma representação binária enviada pelo `Socket`.
|
||||
|
||||
Mensagens específicas devem estender essa classe adicionando os atributos e
|
||||
comportamentos necessários para cada funcionalidade.
|
||||
|
||||
### Heartbeat
|
||||
|
||||
O mecanismo de heartbeat é utilizado para identificar quais usuários estão
|
||||
ativos na rede.
|
||||
|
||||
A aplicação envia periodicamente uma `HeartbeatMessage` contendo informações
|
||||
do usuário e um timestamp. Quando outra instância recebe essa mensagem, o
|
||||
`HeartbeatManager` atualiza o registro do usuário correspondente.
|
||||
|
||||
O fluxo de heartbeat é independente das mensagens dos plugins:
|
||||
|
||||
1. `HeartbeatManager` cria uma `HeartbeatMessage`.
|
||||
2. A mensagem é serializada utilizando `Message.toByteArray()`.
|
||||
3. O `Socket` transmite a mensagem pela rede multicast.
|
||||
4. O `Socket` identifica mensagens de heartbeat recebidas e encaminha ao
|
||||
`HeartbeatManager`.
|
||||
5. O `HeartbeatManager` atualiza a lista de usuários ativos e notifica os
|
||||
listeners.
|
||||
|
||||
## Sistema de plugins
|
||||
|
||||
### Interface Plugin
|
||||
|
||||
A interface `Plugin` define o contrato que deve ser implementado por qualquer
|
||||
extensão da aplicação.
|
||||
|
||||
Um plugin deve fornecer informações básicas de identificação (`name`,
|
||||
`author` e `version`), inicializar seu estado através de `createPlugin()` e
|
||||
participar do sistema de comunicação utilizando mensagens derivadas de
|
||||
`Message`.
|
||||
|
||||
Os principais métodos são:
|
||||
|
||||
#### Identificação
|
||||
|
||||
Os métodos:
|
||||
- `getName()`
|
||||
- `getAuthor()`
|
||||
- `getVersion()`
|
||||
|
||||
fornecem informações utilizadas pela aplicação para identificar o plugin.
|
||||
|
||||
#### Inicialização
|
||||
|
||||
`createPlugin(MainWindow window)`
|
||||
|
||||
É chamado após o carregamento do plugin e permite que ele registre seus
|
||||
componentes na aplicação, como menus ou elementos de interface.
|
||||
|
||||
#### Comunicação
|
||||
|
||||
`getMessage()`
|
||||
|
||||
Deve retornar uma mensagem utilizada pelo plugin para comunicação com outras
|
||||
instâncias da aplicação.
|
||||
|
||||
`receiveMessage(byte[] message)`
|
||||
|
||||
É chamado pela aplicação sempre que uma mensagem é recebida. Cada plugin deve
|
||||
verificar se a mensagem pertence ao seu tipo e realizar o processamento
|
||||
correspondente.
|
||||
|
||||
### Descoberta de plugins
|
||||
|
||||
Para serem reconhecidos, os plugins devem possuir os arquivos de configuração
|
||||
do Java Service Provider Interface (SPI):
|
||||
|
||||
```
|
||||
MeusPlugins
|
||||
|
|
||||
+---META-INF
|
||||
|
|
||||
+---services
|
||||
|
|
||||
+---pitiupi.plugin.Plugin
|
||||
```
|
||||
|
||||
O arquivo `pitiupi.plugin.Plugin` deve conter o nome completo das classes que
|
||||
implementam a interface Plugin:
|
||||
|
||||
```
|
||||
MeusPlugins.plugins.NomeDaClasse
|
||||
```
|
||||
|
||||
Para serem carregados, os plugins devem estar empacotados como arquivos JAR
|
||||
e colocados no diretório plugins da aplicação.
|
||||
|
||||
### Carregamento
|
||||
|
||||
Ao iniciar a aplicação, o `PluginLoader` executa os seguintes passos:
|
||||
|
||||
1. Procura arquivos `.jar` dentro do diretório `plugins`.
|
||||
2. Cria um `URLClassLoader` contendo os JARs encontrados.
|
||||
3. Utiliza `ServiceLoader` para localizar classes que implementam
|
||||
`Plugin`.
|
||||
4. Instancia cada plugin encontrado.
|
||||
5. Chama o método `createPlugin(MainWindow)`.
|
||||
6. Registra o plugin na lista de plugins ativos da aplicação.
|
||||
|
||||
## Interface gráfica
|
||||
|
||||
A interface gráfica da aplicação é baseada em Swing e é centralizada na
|
||||
classe `MainWindow`.
|
||||
|
||||
Durante a inicialização, cada plugin recebe uma referência para a
|
||||
`MainWindow` através do método `createPlugin(MainWindow)`.
|
||||
|
||||
Essa referência permite integrar componentes gráficos à aplicação, sendo a
|
||||
principal forma de extensão a adição de menus à barra de menus:
|
||||
|
||||
```java
|
||||
JMenu menu = new JMenu("Meu Plugin");
|
||||
window.addMenu(menu);
|
||||
|
|
@ -8,6 +8,8 @@ package pitiupi.GUI;
|
|||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* Janela que exibe informações sobre a aplicação, incluindo versão,
|
||||
* descrição e autores.
|
||||
*
|
||||
* @author gustavo
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -20,6 +20,10 @@ import javax.swing.JSpinner;
|
|||
import javax.swing.JTextField;
|
||||
|
||||
/**
|
||||
* Janela de preferencias da aplicação.
|
||||
*
|
||||
* <p>Permite ao usuário informar o nome utilizado na rede e a porta
|
||||
* multicast que será utilizada pela comunicação.</p>
|
||||
*
|
||||
* @author flavio
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -14,9 +14,18 @@ import pitiupi.plugin.Plugin;
|
|||
import pitiupi.control.HeartbeatManager;
|
||||
|
||||
/**
|
||||
* Janela principal da aplicação.
|
||||
*
|
||||
* <p>Responsável por inicializar a interface gráfica e coordenar os
|
||||
* principais componentes da aplicação, incluindo comunicação de rede,
|
||||
* gerenciamento de heartbeat e carregamento de plugins.</p>
|
||||
*
|
||||
* <p>A instância desta classe é compartilhada com os plugins para permitir
|
||||
* integração com a aplicação principal.</p>
|
||||
*
|
||||
* @author flavio
|
||||
* @author tony
|
||||
* @author Gustavo
|
||||
*/
|
||||
public class MainWindow extends javax.swing.JFrame {
|
||||
|
||||
|
|
@ -38,7 +47,12 @@ public class MainWindow extends javax.swing.JFrame {
|
|||
private PluginLoader pluginManager;
|
||||
private final List<Plugin> plugins;
|
||||
|
||||
|
||||
/**
|
||||
* Cria a janela principal da aplicação.
|
||||
*
|
||||
* @param userName nome utilizado para identificação na rede.
|
||||
* @param port porta utilizada na comunicação multicast.
|
||||
*/
|
||||
public MainWindow(String userName, int port) {
|
||||
this.userName = userName;
|
||||
this.port = port;
|
||||
|
|
@ -48,6 +62,14 @@ public class MainWindow extends javax.swing.JFrame {
|
|||
}
|
||||
|
||||
private void initComponents() {
|
||||
initGUI();
|
||||
initSocket();
|
||||
initHeartbeat();
|
||||
initPlugins();
|
||||
this.setSize(new java.awt.Dimension(1024, 768));
|
||||
}
|
||||
|
||||
private void initGUI() {
|
||||
this.setJMenuBar(menuBar);
|
||||
this.setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
|
||||
this.setTitle("Share My Sheet");
|
||||
|
|
@ -66,22 +88,26 @@ public class MainWindow extends javax.swing.JFrame {
|
|||
this.getContentPane().add(statusPanel, java.awt.BorderLayout.PAGE_END);
|
||||
|
||||
this.pack();
|
||||
}
|
||||
|
||||
private void initSocket() {
|
||||
this.socket = new Socket(this);
|
||||
this.socket.start();
|
||||
}
|
||||
|
||||
private void initHeartbeat() {
|
||||
this.heartbeatManager = new HeartbeatManager(this);
|
||||
this.onlineUsersPanel = new OnlineUsersPanel();
|
||||
this.heartbeatManager.addPeerListener(this.onlineUsersPanel);
|
||||
this.getContentPane().add(this.onlineUsersPanel, java.awt.BorderLayout.LINE_END);
|
||||
this.heartbeatManager.start();
|
||||
}
|
||||
|
||||
this.setSize(new java.awt.Dimension(1024, 768));
|
||||
private void initPlugins() {
|
||||
this.pluginManager = new PluginLoader(this);
|
||||
this.pluginManager.loadPlugins();
|
||||
}
|
||||
|
||||
|
||||
public void exit() {
|
||||
this.setVisible(false);
|
||||
this.dispose();
|
||||
|
|
|
|||
|
|
@ -9,8 +9,13 @@ import javax.swing.JMenu;
|
|||
import javax.swing.JMenuBar;
|
||||
|
||||
/**
|
||||
* Barra de menus principal da aplicação.
|
||||
*
|
||||
* <p>Gerencia os menus padrões da interface e disponibiliza um espaço
|
||||
* para que plugins adicionem seus próprios menus.</p>
|
||||
*
|
||||
* @author flavio
|
||||
* @author Gustavo
|
||||
*/
|
||||
public class MenuBar extends JMenuBar {
|
||||
|
||||
|
|
@ -58,8 +63,6 @@ public class MenuBar extends JMenuBar {
|
|||
this.add(helpMenu);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void exitMenuActionPerformed(java.awt.event.ActionEvent evt) {
|
||||
mainWindow.exit();
|
||||
}
|
||||
|
|
@ -74,7 +77,13 @@ public class MenuBar extends JMenuBar {
|
|||
About about = new About();
|
||||
about.setVisible(true);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adiciona um menu fornecido por um plugin à seção de plugins da barra
|
||||
* de menus.
|
||||
*
|
||||
* @param menu menu criado pelo plugin.
|
||||
*/
|
||||
public void addPlugin(JMenu menu){
|
||||
this.pluginMenu.add(menu);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,10 @@ import javax.swing.JScrollPane;
|
|||
import javax.swing.SwingUtilities;
|
||||
import pitiupi.control.PeerInfo;
|
||||
import pitiupi.control.PeerListener;
|
||||
|
||||
/**
|
||||
* Painel da interface gráfica responsável por exibir os usuários ativos
|
||||
* na rede.
|
||||
*
|
||||
* @author tony
|
||||
*/
|
||||
|
|
@ -30,6 +33,11 @@ public class OnlineUsersPanel extends JPanel implements PeerListener {
|
|||
add(new JScrollPane(userList), BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Atualiza a lista de usuários exibida no painel.
|
||||
*
|
||||
* @param peers lista atualizada de usuários ativos na rede.
|
||||
*/
|
||||
@Override
|
||||
public void onPeersChanged(List<PeerInfo> peers) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ import java.util.logging.Logger;
|
|||
* @author flavio
|
||||
*/
|
||||
public class Main {
|
||||
|
||||
/**
|
||||
* @param args the command line arguments
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -15,6 +15,11 @@ import java.util.logging.Logger;
|
|||
import pitiupi.GUI.MainWindow;
|
||||
import pitiupi.net.HeartbeatMessage;
|
||||
/**
|
||||
* Gerencia o mecanismo de heartbeat da aplicação.
|
||||
*
|
||||
* <p>Responsável por anunciar a presença da aplicação na rede, receber
|
||||
* heartbeats de outros usuários, controlar o tempo desde a última atividade
|
||||
* dos peers e notificar listeners quando a lista de usuários ativos muda.</p>
|
||||
*
|
||||
* @author tony
|
||||
*/
|
||||
|
|
@ -54,6 +59,17 @@ public class HeartbeatManager {
|
|||
}
|
||||
|
||||
// Chamado pelo Socket quando um pacote é identificado como heartbeat
|
||||
/**
|
||||
* Processa uma mensagem de heartbeat recebida de outro usuário.
|
||||
*
|
||||
* <p>Atualiza a informação do peer correspondente e notifica os listeners
|
||||
* caso um novo usuário seja identificado.</p>
|
||||
*
|
||||
* <p>Mensagens de heartbeat enviadas pela própria aplicação são ignoradas.</p>
|
||||
*
|
||||
* @param msg mensagem de heartbeat recebida.
|
||||
* @param from endereço de rede do usuário que enviou a mensagem.
|
||||
*/
|
||||
public void receiveHeartbeat(HeartbeatMessage msg, InetAddress from) {
|
||||
// ignora o próprio heartbeat
|
||||
if (msg.getUserName().equals(mainWindow.getUserName())) {
|
||||
|
|
@ -86,6 +102,14 @@ public class HeartbeatManager {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adiciona um listener para receber atualizações sobre os peers conhecidos.
|
||||
*
|
||||
* <p>O listener recebe imediatamente o estado atual dos peers ao ser
|
||||
* registrado.</p>
|
||||
*
|
||||
* @param l listener que será notificado sobre alterações.
|
||||
*/
|
||||
public void addPeerListener(PeerListener l) {
|
||||
listeners.add(l);
|
||||
l.onPeersChanged(new ArrayList<>(peers.values()));
|
||||
|
|
|
|||
|
|
@ -2,6 +2,11 @@ package pitiupi.control;
|
|||
|
||||
import java.net.InetAddress;
|
||||
/**
|
||||
* Representa um usuário identificado na rede e as informações necessárias
|
||||
* para acompanhar sua presença através de mensagens de heartbeat.
|
||||
*
|
||||
* <p>Armazena o nome do usuário, seu endereço de rede e o instante da
|
||||
* última mensagem recebida.</p>
|
||||
*
|
||||
* @author tony
|
||||
*/
|
||||
|
|
@ -29,6 +34,11 @@ public class PeerInfo {
|
|||
return lastSeen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Atualiza o instante da última atividade do usuário.
|
||||
*
|
||||
* @param timestamp novo instante de atividade.
|
||||
*/
|
||||
public void touch(long timestamp) {
|
||||
this.lastSeen = timestamp;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,21 @@
|
|||
package pitiupi.control;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Interface para receber notificações sobre alterações nos usuários
|
||||
* conhecidos na rede.
|
||||
*
|
||||
* <p>Implementações desta interface são notificadas sempre que a lista
|
||||
* de usuários ativos é modificada.</p>
|
||||
*
|
||||
* @author tony
|
||||
*/
|
||||
public interface PeerListener {
|
||||
/**
|
||||
* Chamado quando a lista de usuários conhecidos na rede é alterada.
|
||||
*
|
||||
* @param peers lista atualizada de usuários ativos.
|
||||
*/
|
||||
void onPeersChanged(List<PeerInfo> peers);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,12 @@ import pitiupi.Main;
|
|||
import pitiupi.plugin.Plugin;
|
||||
|
||||
/**
|
||||
* Responsável por localizar, carregar e registrar os plugins
|
||||
* presentes no diretório {@code plugins}.
|
||||
*
|
||||
* <p>Os plugins são descobertos utilizando {@link java.util.ServiceLoader}
|
||||
* e devem estar empacotados como arquivos JAR contendo a configuração
|
||||
* {@code META-INF/services} correspondente.</p>
|
||||
* @author flavio
|
||||
*/
|
||||
public class PluginLoader {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
package pitiupi.net;
|
||||
/**
|
||||
* Mensagem utilizada para sinalizar a presença de um usuário na rede.
|
||||
*
|
||||
* <p>É enviada periodicamente para permitir que a aplicação identifique
|
||||
* usuários ativos e mantenha o controle dos participantes conectados.</p>
|
||||
*
|
||||
* @author tony
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -12,11 +12,25 @@ import java.io.ObjectOutputStream;
|
|||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Classe base para as mensagens trocadas entre a aplicação e os plugins.
|
||||
*
|
||||
* <p>As mensagens devem estender esta classe para utilizar o sistema de
|
||||
* comunicação da aplicação. Subclasses podem adicionar os dados e a lógica
|
||||
* necessários para representar diferentes tipos de mensagens.</p>
|
||||
*
|
||||
* <p>Por implementar {@link Serializable}, objetos derivados desta classe
|
||||
* podem ser convertidos em bytes para transmissão pela rede.</p>
|
||||
*
|
||||
* @author flavio
|
||||
*/
|
||||
public abstract class Message implements Serializable{
|
||||
|
||||
/**
|
||||
* Serializa a mensagem para um vetor de bytes.
|
||||
*
|
||||
* @return representação serializada da mensagem.
|
||||
* @throws IOException caso ocorra um erro durante a serialização.
|
||||
*/
|
||||
public byte[] toByteArray() throws IOException {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ObjectOutput out = new ObjectOutputStream(baos);
|
||||
|
|
|
|||
|
|
@ -20,6 +20,10 @@ import pitiupi.plugin.Plugin;
|
|||
import pitiupi.net.HeartbeatMessage;
|
||||
|
||||
/**
|
||||
* Responsável pela comunicação multicast entre a aplicação e os plugins.
|
||||
*
|
||||
* <p>Esta classe gerencia o envio e o recebimento de mensagens, além de
|
||||
* manter a conexão com o grupo multicast utilizado pela aplicação.</p>
|
||||
*
|
||||
* @author flavio
|
||||
* @author tony
|
||||
|
|
@ -31,6 +35,11 @@ public class Socket extends Thread {
|
|||
private MainWindow main;
|
||||
public final static String INET_ADDR = "224.0.0.3";
|
||||
|
||||
/**
|
||||
* Cria e inicializa a conexão multicast utilizada pela aplicação.
|
||||
*
|
||||
* @param main janela principal da aplicação.
|
||||
*/
|
||||
public Socket(MainWindow main) {
|
||||
this.main = main;
|
||||
try {
|
||||
|
|
@ -50,12 +59,29 @@ public class Socket extends Thread {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Envia uma mensagem para o grupo multicast da aplicação.
|
||||
*
|
||||
* @param msg mensagem serializada a ser enviada.
|
||||
* @throws IOException caso ocorra um erro durante o envio da mensagem.
|
||||
*/
|
||||
public void send(byte[] msg) throws IOException {
|
||||
DatagramPacket msgPacket;
|
||||
msgPacket = new DatagramPacket(msg, msg.length, this.address, this.main.getPort());
|
||||
multicastSocket.send(msgPacket);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Inicia o loop de recepção de mensagens da aplicação.
|
||||
*
|
||||
* <p>As mensagens recebidas são verificadas inicialmente para identificar
|
||||
* mensagens de heartbeat. Caso não sejam heartbeats, seu conteúdo é
|
||||
* encaminhado para todos os plugins carregados, que decidem se devem ou
|
||||
* não processá-lo.</p>
|
||||
*
|
||||
* @throws IOException caso ocorra um erro durante a recepção da mensagem.
|
||||
* @throws ClassNotFoundException caso a desserialização de uma mensagem falhe.
|
||||
*/
|
||||
public void receive() throws UnknownHostException, IOException, ClassNotFoundException {
|
||||
byte[] buf = new byte[256000];
|
||||
while (true) {
|
||||
|
|
@ -74,7 +100,14 @@ public class Socket extends Thread {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tenta desserializar os dados recebidos como uma {@code HeartbeatMessage}.
|
||||
*
|
||||
* @param data dados serializados da mensagem.
|
||||
* @return a mensagem desserializada caso os dados representem uma
|
||||
* {@code HeartbeatMessage}; caso contrário, {@code null}.
|
||||
*/
|
||||
private HeartbeatMessage tryParseHeartbeat(byte[] data) {
|
||||
try {
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(data);
|
||||
|
|
|
|||
|
|
@ -9,6 +9,10 @@ import pitiupi.GUI.MainWindow;
|
|||
import pitiupi.net.Message;
|
||||
|
||||
/**
|
||||
* Interface base para plugins da aplicação.
|
||||
*
|
||||
* <p>Cada plugin deve implementar esta interface para ser carregado
|
||||
* pela aplicação e participar do sistema de comunicação por mensagens.</p>
|
||||
*
|
||||
* @author flavio
|
||||
*/
|
||||
|
|
@ -17,7 +21,30 @@ public interface Plugin {
|
|||
public String getName();
|
||||
public String getAuthor();
|
||||
public String getVersion();
|
||||
|
||||
/**
|
||||
* Inicializa o plugin.
|
||||
*
|
||||
* <p>Este método é chamado pela aplicação após o carregamento do plugin.</p>
|
||||
*
|
||||
* @param window janela principal da aplicação.
|
||||
*/
|
||||
public void createPlugin(MainWindow window);
|
||||
|
||||
/**
|
||||
* Retorna uma mensagem utilizada pelo plugin.
|
||||
*
|
||||
* @return mensagem criada pelo plugin.
|
||||
*/
|
||||
public Message getMessage();
|
||||
|
||||
/**
|
||||
* Recebe uma mensagem enviada pela aplicação.
|
||||
*
|
||||
* <p>A mensagem é recebida em formato serializado. O plugin deve verificar
|
||||
* se a mensagem pertence ao seu tipo e realizar o processamento necessário.</p>
|
||||
*
|
||||
* @param message mensagem serializada recebida.
|
||||
*/
|
||||
public void receiveMessage(byte[] message);
|
||||
}
|
||||
Loading…
Reference in New Issue