WIP
This commit is contained in:
1 parent
b5bbd1df2d
commit
7168431bcd
9 files changed
+311
-216
No files matched your search
@@ -5,13 +5,11 @@
|
|||||||
*/
|
*/
|
||||||
package pitiupi.GUI;
|
package pitiupi.GUI;
|
||||||
|
|
||||||
import pitiupi.net.tcp.SocketTCP;
|
import pitiupi.control.ConnectionManager;
|
||||||
import pitiupi.net.udp.SocketUDP;
|
import pitiupi.control.PluginManager;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import javax.swing.JMenu;
|
import javax.swing.JMenu;
|
||||||
import pitiupi.control.PluginLoader;
|
|
||||||
import pitiupi.plugin.Plugin;
|
|
||||||
import pitiupi.control.HeartbeatManager;
|
import pitiupi.control.HeartbeatManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -36,20 +34,12 @@ public class MainWindow extends javax.swing.JFrame {
|
|||||||
private javax.swing.JPanel statusPanel;
|
private javax.swing.JPanel statusPanel;
|
||||||
private javax.swing.JTabbedPane tabbedPane;
|
private javax.swing.JTabbedPane tabbedPane;
|
||||||
|
|
||||||
private HeartbeatManager heartbeatManager;
|
|
||||||
private OnlineUsersPanel onlineUsersPanel;
|
private OnlineUsersPanel onlineUsersPanel;
|
||||||
|
|
||||||
|
|
||||||
private SocketUDP socketUDP;
|
|
||||||
private SocketTCP socketTCP;
|
|
||||||
|
|
||||||
private String userName;
|
private String userName;
|
||||||
private int port;
|
|
||||||
|
|
||||||
private String pitiupiIdentifier;
|
private ConnectionManager connectionManager;
|
||||||
|
private PluginManager pluginManager;
|
||||||
private PluginLoader pluginManager;
|
|
||||||
private final List<Plugin> plugins;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cria a janela principal da aplicação.
|
* Cria a janela principal da aplicação.
|
||||||
@@ -59,22 +49,18 @@ public class MainWindow extends javax.swing.JFrame {
|
|||||||
*/
|
*/
|
||||||
public MainWindow(String userName, int port) {
|
public MainWindow(String userName, int port) {
|
||||||
this.userName = userName;
|
this.userName = userName;
|
||||||
this.port = port;
|
|
||||||
this.pitiupiIdentifier = "Pitiupi.Alice.2026";
|
pluginManager = new PluginManager(this);
|
||||||
this.menuBar = new MenuBar(this);
|
loadPlugins();
|
||||||
this.plugins = new ArrayList<>();
|
|
||||||
this.initComponents();
|
connectionManager = new ConnectionManager(this, pluginManager, port);
|
||||||
|
|
||||||
|
menuBar = new MenuBar(this);
|
||||||
|
|
||||||
|
initComponents();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initComponents() {
|
private void initComponents() {
|
||||||
initGUI();
|
|
||||||
initSocket();
|
|
||||||
initHeartbeat();
|
|
||||||
initPlugins();
|
|
||||||
this.setSize(new java.awt.Dimension(1024, 768));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initGUI() {
|
|
||||||
this.setJMenuBar(menuBar);
|
this.setJMenuBar(menuBar);
|
||||||
this.setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
|
this.setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
|
||||||
this.setTitle("Share My Sheet");
|
this.setTitle("Share My Sheet");
|
||||||
@@ -86,34 +72,19 @@ public class MainWindow extends javax.swing.JFrame {
|
|||||||
|
|
||||||
jScrollPane1.setViewportView(tabbedPane);
|
jScrollPane1.setViewportView(tabbedPane);
|
||||||
statusPanel.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.RIGHT));
|
statusPanel.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.RIGHT));
|
||||||
status.setText("Connected on port " + this.port + " name " + this.userName);
|
updateStatus();
|
||||||
statusPanel.add(status);
|
statusPanel.add(status);
|
||||||
|
|
||||||
this.getContentPane().add(jScrollPane1, java.awt.BorderLayout.CENTER);
|
this.getContentPane().add(jScrollPane1, java.awt.BorderLayout.CENTER);
|
||||||
this.getContentPane().add(statusPanel, java.awt.BorderLayout.PAGE_END);
|
this.getContentPane().add(statusPanel, java.awt.BorderLayout.PAGE_END);
|
||||||
|
|
||||||
this.pack();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initSocket() {
|
|
||||||
this.socketUDP = new SocketUDP(this);
|
|
||||||
this.socketTCP = new SocketTCP(this);
|
|
||||||
|
|
||||||
this.socketUDP.start();
|
|
||||||
this.socketTCP.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initHeartbeat() {
|
|
||||||
this.heartbeatManager = new HeartbeatManager(this);
|
|
||||||
this.onlineUsersPanel = new OnlineUsersPanel();
|
this.onlineUsersPanel = new OnlineUsersPanel();
|
||||||
this.heartbeatManager.addPeerListener(this.onlineUsersPanel);
|
this.connectionManager.addPeerListener(onlineUsersPanel);
|
||||||
this.getContentPane().add(this.onlineUsersPanel, java.awt.BorderLayout.LINE_END);
|
this.getContentPane().add(this.onlineUsersPanel, java.awt.BorderLayout.LINE_END);
|
||||||
this.heartbeatManager.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initPlugins() {
|
this.pack();
|
||||||
this.pluginManager = new PluginLoader(this);
|
|
||||||
this.pluginManager.loadPlugins();
|
this.setSize(new java.awt.Dimension(1024, 768));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void exit() {
|
public void exit() {
|
||||||
@@ -122,65 +93,29 @@ public class MainWindow extends javax.swing.JFrame {
|
|||||||
System.exit(0);
|
System.exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public HeartbeatManager getHeartbeatManager() {
|
|
||||||
return heartbeatManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUserName(){
|
public String getUserName(){
|
||||||
return this.userName;
|
return this.userName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getIdentifier(){
|
public ConnectionManager getConnectionManager() {
|
||||||
return this.pitiupiIdentifier;
|
return connectionManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadPlugins() {
|
||||||
|
pluginManager.loadPlugins();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addMenu(JMenu menu) {
|
public void addMenu(JMenu menu) {
|
||||||
this.menuBar.addPlugin(menu);
|
this.menuBar.addPlugin(menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getPort() {
|
|
||||||
return this.port;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SocketUDP getSocketUDP() {
|
|
||||||
return this.socketUDP;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SocketTCP getSocketTCP() {
|
|
||||||
return this.socketTCP;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Plugin> getPlugins() {
|
|
||||||
return plugins;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUserName(String userName) {
|
public void setUserName(String userName) {
|
||||||
this.userName = userName;
|
this.userName = userName;
|
||||||
updateStatus();
|
updateStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPort(int port) {
|
|
||||||
this.port = port;
|
|
||||||
reconnect();
|
|
||||||
updateStatus();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateStatus() {
|
private void updateStatus() {
|
||||||
this.status.setText("Connected on port " + this.port + " name " + this.userName);
|
this.status.setText("Connected on port " + connectionManager + " name " + this.userName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void reconnect() {
|
|
||||||
if (this.socketUDP != null) {
|
|
||||||
this.socketUDP.close();
|
|
||||||
}
|
|
||||||
if (this.socketTCP != null) {
|
|
||||||
this.socketTCP.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.socketUDP = new SocketUDP(this);
|
|
||||||
this.socketTCP = new SocketTCP(this);
|
|
||||||
|
|
||||||
this.socketUDP.start();
|
|
||||||
this.socketTCP.start();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -80,7 +80,7 @@ public class MenuBar extends JMenuBar {
|
|||||||
login.setVisible(true);
|
login.setVisible(true);
|
||||||
|
|
||||||
mainWindow.setUserName(login.getName());
|
mainWindow.setUserName(login.getName());
|
||||||
mainWindow.setPort(login.getPort());
|
mainWindow.getConnectionManager().setPort(login.getPort());
|
||||||
|
|
||||||
login.dispose();
|
login.dispose();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,104 @@
|
|||||||
|
package pitiupi.control;
|
||||||
|
|
||||||
|
import pitiupi.GUI.MainWindow;
|
||||||
|
import pitiupi.net.HeartbeatMessage;
|
||||||
|
import pitiupi.net.Message;
|
||||||
|
import pitiupi.net.tcp.SocketTCP;
|
||||||
|
import pitiupi.net.tcp.TcpConnection;
|
||||||
|
import pitiupi.net.udp.SocketUDP;
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
|
|
||||||
|
public class ConnectionManager {
|
||||||
|
private final String pitiupiIdentifier;
|
||||||
|
|
||||||
|
private PluginManager pluginManager;
|
||||||
|
|
||||||
|
private HeartbeatManager heartbeatManager;
|
||||||
|
|
||||||
|
private SocketTCP socketTCP;
|
||||||
|
private SocketUDP socketUDP;
|
||||||
|
private int port;
|
||||||
|
|
||||||
|
public ConnectionManager(MainWindow main, PluginManager pluginManager, int port) {
|
||||||
|
this.pluginManager = pluginManager;
|
||||||
|
this.port = port;
|
||||||
|
|
||||||
|
pitiupiIdentifier = "Pitiupi.Alice.2026";
|
||||||
|
|
||||||
|
reconnect();
|
||||||
|
|
||||||
|
heartbeatManager = new HeartbeatManager(main, this);
|
||||||
|
heartbeatManager.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public TcpConnection connectPluginTcp(InetAddress destinationAdress, String senderId, String receiverId) {
|
||||||
|
return socketTCP.createPrivateConnection(destinationAdress, senderId, receiverId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean sendTcp(Message message, InetAddress destinationAddress) {
|
||||||
|
return socketTCP.send(message, destinationAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean sendUdpUnicast(Message message, InetAddress destinationAddress) {
|
||||||
|
try {
|
||||||
|
socketUDP.sendUnicast(message, destinationAddress);
|
||||||
|
return true;
|
||||||
|
} catch (Exception ex) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean sendUdpMulticast(Message message) {
|
||||||
|
try {
|
||||||
|
socketUDP.sendMulticast(message);
|
||||||
|
return true;
|
||||||
|
} catch (Exception ex) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void broadcastLocal(Message message) {
|
||||||
|
pluginManager.handlePublicMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean sendLocal(byte[] message, String receiverId) {
|
||||||
|
return pluginManager.handlePrivateMessage(message, receiverId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addPeerListener(PeerListener peerListener) {
|
||||||
|
heartbeatManager.addPeerListener(peerListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void receiveHeartbeat(HeartbeatMessage message, InetAddress destinationAddress) {
|
||||||
|
heartbeatManager.receiveHeartbeat(message, destinationAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPort(int port) {
|
||||||
|
this.port = port;
|
||||||
|
reconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPort() {
|
||||||
|
return port;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIdentifier(){
|
||||||
|
return this.pitiupiIdentifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void reconnect() {
|
||||||
|
if (this.socketUDP != null) {
|
||||||
|
this.socketUDP.close();
|
||||||
|
}
|
||||||
|
if (this.socketTCP != null) {
|
||||||
|
this.socketTCP.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.socketUDP = new SocketUDP(this, pluginManager);
|
||||||
|
this.socketTCP = new SocketTCP(this, pluginManager);
|
||||||
|
|
||||||
|
this.socketUDP.start();
|
||||||
|
this.socketTCP.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -30,6 +30,7 @@ public class HeartbeatManager {
|
|||||||
private static final long PEER_TIMEOUT_MS = 15000; // ~3 batimentos perdidos
|
private static final long PEER_TIMEOUT_MS = 15000; // ~3 batimentos perdidos
|
||||||
|
|
||||||
private final MainWindow mainWindow;
|
private final MainWindow mainWindow;
|
||||||
|
private final ConnectionManager connectionManager;
|
||||||
private final Map<String, PeerInfo> peers = new ConcurrentHashMap<>();
|
private final Map<String, PeerInfo> peers = new ConcurrentHashMap<>();
|
||||||
private final List<PeerListener> listeners = new CopyOnWriteArrayList<>();
|
private final List<PeerListener> listeners = new CopyOnWriteArrayList<>();
|
||||||
private ScheduledExecutorService scheduler;
|
private ScheduledExecutorService scheduler;
|
||||||
@@ -41,8 +42,9 @@ public class HeartbeatManager {
|
|||||||
* @param mainWindow janela principal utilizada para obter o nome do usuário
|
* @param mainWindow janela principal utilizada para obter o nome do usuário
|
||||||
* e o socket de comunicação.
|
* e o socket de comunicação.
|
||||||
*/
|
*/
|
||||||
public HeartbeatManager(MainWindow mainWindow) {
|
public HeartbeatManager(MainWindow mainWindow, ConnectionManager connectionManager) {
|
||||||
this.mainWindow = mainWindow;
|
this.mainWindow = mainWindow;
|
||||||
|
this.connectionManager = connectionManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -64,12 +66,8 @@ public class HeartbeatManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void announce() {
|
private void announce() {
|
||||||
try {
|
|
||||||
HeartbeatMessage msg = new HeartbeatMessage(mainWindow.getUserName(), instanceId);
|
HeartbeatMessage msg = new HeartbeatMessage(mainWindow.getUserName(), instanceId);
|
||||||
mainWindow.getSocketUDP().sendMulticast(msg.toByteArray());
|
connectionManager.sendUdpMulticast(msg);
|
||||||
} catch (IOException ex) {
|
|
||||||
Logger.getLogger(HeartbeatManager.class.getName()).log(Level.WARNING, "Falha ao enviar heartbeat", ex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Chamado pelo Socket quando um pacote é identificado como heartbeat
|
// Chamado pelo Socket quando um pacote é identificado como heartbeat
|
||||||
|
|||||||
@@ -4,14 +4,12 @@
|
|||||||
*/
|
*/
|
||||||
package pitiupi.control;
|
package pitiupi.control;
|
||||||
|
|
||||||
import java.awt.List;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLClassLoader;
|
import java.net.URLClassLoader;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.ServiceLoader;
|
|
||||||
import java.util.Vector;
|
|
||||||
import pitiupi.GUI.MainWindow;
|
import pitiupi.GUI.MainWindow;
|
||||||
import pitiupi.Main;
|
import pitiupi.Main;
|
||||||
import pitiupi.plugin.Plugin;
|
import pitiupi.plugin.Plugin;
|
||||||
@@ -33,7 +31,7 @@ public class PluginLoader {
|
|||||||
this.mainWindow = main;
|
this.mainWindow = main;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadPlugins() {
|
public void loadPlugins(List<Plugin> plugins, HashSet<String> loadedJars) {
|
||||||
File pluginDir = new File("plugins");
|
File pluginDir = new File("plugins");
|
||||||
File[] jarFiles = pluginDir.listFiles((dir, name) -> name.endsWith(".jar"));
|
File[] jarFiles = pluginDir.listFiles((dir, name) -> name.endsWith(".jar"));
|
||||||
|
|
||||||
@@ -42,33 +40,34 @@ public class PluginLoader {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
// 2. Convert jar file paths into URLs
|
|
||||||
ArrayList urls = new ArrayList();
|
|
||||||
for (File file : jarFiles) {
|
for (File file : jarFiles) {
|
||||||
urls.add(file.toURI().toURL());
|
|
||||||
System.out.println("Discovered plugin package: " + file.getName());
|
if (loadedJars.contains(file.getName())) {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Create a class loader isolated from the application's default loader
|
System.out.println("Discovered plugin package: " + file.getName());
|
||||||
URLClassLoader pluginClassLoader = new URLClassLoader(
|
|
||||||
(URL[])urls.toArray(new URL[0]),
|
try {
|
||||||
|
URLClassLoader classLoader = new URLClassLoader(
|
||||||
|
new URL[]{file.toURI().toURL()},
|
||||||
Main.class.getClassLoader()
|
Main.class.getClassLoader()
|
||||||
);
|
);
|
||||||
System.out.println(pluginClassLoader);
|
|
||||||
|
|
||||||
// 4. Locate and instantiate all classes implementing the Plugin interface
|
ServiceLoader<Plugin> serviceLoader = ServiceLoader.load(Plugin.class, classLoader);
|
||||||
ServiceLoader<Plugin> serviceLoader = ServiceLoader.load(Plugin.class, pluginClassLoader);
|
|
||||||
|
|
||||||
System.out.println("\n--- Executing Discovered Plugins ---" + serviceLoader.findFirst());
|
|
||||||
for (Plugin plugin : serviceLoader) {
|
for (Plugin plugin : serviceLoader) {
|
||||||
System.out.println("Loading: " + plugin.getName());
|
System.out.println("Loading: " + plugin.getName());
|
||||||
|
|
||||||
plugin.createPlugin(this.mainWindow);
|
plugin.createPlugin(this.mainWindow);
|
||||||
this.mainWindow.getPlugins().add(plugin);
|
plugins.add(plugin);
|
||||||
|
loadedJars.add(file.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (MalformedURLException e) {
|
} catch (Exception e) {
|
||||||
System.out.println(e.toString());
|
System.out.println("Failed to load plugin " + file.getName());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
package pitiupi.control;
|
||||||
|
|
||||||
|
import pitiupi.GUI.MainWindow;
|
||||||
|
import pitiupi.net.Message;
|
||||||
|
import pitiupi.net.tcp.TcpConnection;
|
||||||
|
import pitiupi.plugin.Plugin;
|
||||||
|
import pitiupi.plugin.PrivateConnectionPlugin;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class PluginManager {
|
||||||
|
private PluginLoader pluginLoader;
|
||||||
|
private final List<Plugin> plugins;
|
||||||
|
private final HashSet<String> loadedJars;
|
||||||
|
|
||||||
|
public PluginManager(MainWindow main) {
|
||||||
|
this.pluginLoader = new PluginLoader(main);
|
||||||
|
this.plugins = new ArrayList<>();
|
||||||
|
this.loadedJars = new HashSet<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadPlugins() {
|
||||||
|
pluginLoader.loadPlugins(plugins, loadedJars);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handlePublicMessage(Message msg) {
|
||||||
|
for (Plugin plugin : plugins) {
|
||||||
|
plugin.receiveMessage(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Plugin getPlugin(String pluginId) {
|
||||||
|
for (Plugin plugin : plugins) {
|
||||||
|
if (plugin.getIdentifier().equals(pluginId)) return plugin;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean handlePrivateMessage(byte[] msg, String receiverId) {
|
||||||
|
Plugin plugin = getPlugin(receiverId);
|
||||||
|
if (plugin == null) return false;
|
||||||
|
|
||||||
|
if (plugin instanceof PrivateConnectionPlugin privatePlugin) {
|
||||||
|
privatePlugin.receiveBytes(msg);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean handleConnection(TcpConnection connection, String receiverId) {
|
||||||
|
Plugin plugin = getPlugin(receiverId);
|
||||||
|
if (plugin == null) return false;
|
||||||
|
|
||||||
|
if (plugin instanceof PrivateConnectionPlugin privatePlugin) {
|
||||||
|
privatePlugin.receivePrivateConnection(connection);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handleDisconnection(TcpConnection connection, String receiverId) {
|
||||||
|
Plugin plugin = getPlugin(receiverId);
|
||||||
|
if (plugin instanceof PrivateConnectionPlugin privatePlugin) {
|
||||||
|
privatePlugin.onSocketClosed(connection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,11 +1,12 @@
|
|||||||
package pitiupi.net.tcp;
|
package pitiupi.net.tcp;
|
||||||
|
|
||||||
import pitiupi.GUI.MainWindow;
|
import pitiupi.GUI.MainWindow;
|
||||||
|
import pitiupi.control.ConnectionManager;
|
||||||
|
import pitiupi.control.PluginManager;
|
||||||
import pitiupi.net.Message;
|
import pitiupi.net.Message;
|
||||||
import pitiupi.plugin.Plugin;
|
import pitiupi.plugin.Plugin;
|
||||||
import pitiupi.plugin.PrivateConnectionPlugin;
|
import pitiupi.plugin.PrivateConnectionPlugin;
|
||||||
|
|
||||||
import javax.swing.*;
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@@ -35,12 +36,13 @@ public class SocketTCP extends Thread {
|
|||||||
|
|
||||||
private final ExecutorService connectionExecutor = Executors.newCachedThreadPool();
|
private final ExecutorService connectionExecutor = Executors.newCachedThreadPool();
|
||||||
|
|
||||||
private final ConnectionManager connectionManager;
|
private final TcpConnectionManager tcpConnectionManager;
|
||||||
|
|
||||||
private ServerSocket serverSocket;
|
private ServerSocket serverSocket;
|
||||||
private InetAddress address;
|
private InetAddress address;
|
||||||
|
|
||||||
private final MainWindow main;
|
private final ConnectionManager connectionManager;
|
||||||
|
private final PluginManager pluginManager;
|
||||||
|
|
||||||
private volatile boolean running = true;
|
private volatile boolean running = true;
|
||||||
|
|
||||||
@@ -51,15 +53,18 @@ public class SocketTCP extends Thread {
|
|||||||
* com os peers são estabelecidas sob demanda durante o envio ou aceitas
|
* com os peers são estabelecidas sob demanda durante o envio ou aceitas
|
||||||
* quando iniciadas por outros peers.</p>
|
* quando iniciadas por outros peers.</p>
|
||||||
*
|
*
|
||||||
* @param main janela principal da aplicação, usada para obter a porta,
|
* @param connectionManager interface de conexão da aplicação, usada para obter a porta,
|
||||||
* o identificador local e os plugins disponíveis.
|
* o identificador local e os plugins disponíveis.
|
||||||
*/
|
*/
|
||||||
public SocketTCP(MainWindow main) {
|
public SocketTCP(ConnectionManager connectionManager, PluginManager pluginManager) {
|
||||||
this.main = main;
|
this.connectionManager = connectionManager;
|
||||||
|
this.pluginManager = pluginManager;
|
||||||
|
|
||||||
logger = Logger.getLogger(getClass().getName());
|
logger = Logger.getLogger(getClass().getName());
|
||||||
connectionManager = new ConnectionManager();
|
tcpConnectionManager = new TcpConnectionManager();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
serverSocket = new ServerSocket(main.getPort());
|
serverSocket = new ServerSocket(connectionManager.getPort());
|
||||||
address = InetAddress.getByName(InetAddress.getLocalHost().getHostAddress());
|
address = InetAddress.getByName(InetAddress.getLocalHost().getHostAddress());
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
System.out.println("There is no socket connection. Sorry.");
|
System.out.println("There is no socket connection. Sorry.");
|
||||||
@@ -75,28 +80,36 @@ public class SocketTCP extends Thread {
|
|||||||
* do envio. Falhas durante o estabelecimento ou envio são registradas na
|
* do envio. Falhas durante o estabelecimento ou envio são registradas na
|
||||||
* saída padrão e não são propagadas ao chamador.</p>
|
* saída padrão e não são propagadas ao chamador.</p>
|
||||||
*
|
*
|
||||||
* @param msg mensagem serializada em bytes que será enviada.
|
* @param msg mensagem que será enviada.
|
||||||
* @param destinationAddress endereço IP do peer que receberá a mensagem.
|
* @param destinationAddress endereço IP do peer que receberá a mensagem.
|
||||||
*/
|
*/
|
||||||
public void send(byte[] msg, InetAddress destinationAddress) {
|
public boolean send(Message msg, InetAddress destinationAddress) {
|
||||||
try {
|
try {
|
||||||
TcpConnection connection = getPublicConnection(destinationAddress, main.getIdentifier(), main.getIdentifier());
|
TcpConnection connection = getPublicConnection(
|
||||||
|
destinationAddress,
|
||||||
|
connectionManager.getIdentifier(),
|
||||||
|
connectionManager.getIdentifier()
|
||||||
|
);
|
||||||
|
|
||||||
if (connection == null) {
|
if (connection == null) {
|
||||||
System.out.println("Could not establish TCP connection.");
|
System.out.println("Could not establish TCP connection.");
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
connection.send(msg);
|
|
||||||
|
connection.send(msg.toByteArray());
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
System.out.println("Could not send TCP message.");
|
System.out.println("Could not send TCP message.");
|
||||||
System.out.println(ex.toString());
|
System.out.println(ex.toString());
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Estabelece uma conexão TCP privada com um plugin específico do peer de destino.
|
* Estabelece uma conexão TCP privada com um plugin específico do peer de destino.
|
||||||
*
|
*
|
||||||
* <p>A conexão é criada como privada e passa a ser gerenciada pelo
|
* <p>A conexão é criada como privada e passa a ser gerenciada pelo
|
||||||
* {@link ConnectionManager}. O método também inicia a tarefa responsável
|
* {@link TcpConnectionManager}. O método também inicia a tarefa responsável
|
||||||
* por receber os dados dessa conexão.</p>
|
* por receber os dados dessa conexão.</p>
|
||||||
*
|
*
|
||||||
* @param destinationAddress endereço IP do peer de destino.
|
* @param destinationAddress endereço IP do peer de destino.
|
||||||
@@ -115,11 +128,11 @@ public class SocketTCP extends Thread {
|
|||||||
* Obtém uma conexão TCP pública existente com o peer de destino ou estabelece
|
* Obtém uma conexão TCP pública existente com o peer de destino ou estabelece
|
||||||
* uma nova caso não exista uma conexão válida.
|
* uma nova caso não exista uma conexão válida.
|
||||||
*
|
*
|
||||||
* <p>As conexões públicas são gerenciadas pelo {@link ConnectionManager}.
|
* <p>As conexões públicas são gerenciadas pelo {@link TcpConnectionManager}.
|
||||||
* O método primeiro verifica se já existe uma conexão pública registrada
|
* O método primeiro verifica se já existe uma conexão pública registrada
|
||||||
* para o endereço de destino e, caso ela exista e não esteja fechada,
|
* para o endereço de destino e, caso ela exista e não esteja fechada,
|
||||||
* reutiliza-a. Caso contrário, uma nova conexão pública é estabelecida,
|
* reutiliza-a. Caso contrário, uma nova conexão pública é estabelecida,
|
||||||
* registrada no {@link ConnectionManager} e disponibilizada para uso.</p>
|
* registrada no {@link TcpConnectionManager} e disponibilizada para uso.</p>
|
||||||
*
|
*
|
||||||
* <p>O acesso ao método é sincronizado para evitar que múltiplas threads
|
* <p>O acesso ao método é sincronizado para evitar que múltiplas threads
|
||||||
* estabeleçam simultaneamente conexões públicas para o mesmo peer.</p>
|
* estabeleçam simultaneamente conexões públicas para o mesmo peer.</p>
|
||||||
@@ -133,7 +146,7 @@ public class SocketTCP extends Thread {
|
|||||||
private synchronized TcpConnection getPublicConnection(InetAddress destinationAddress, String senderId, String receiverId) {
|
private synchronized TcpConnection getPublicConnection(InetAddress destinationAddress, String senderId, String receiverId) {
|
||||||
TcpConnection connection;
|
TcpConnection connection;
|
||||||
|
|
||||||
connection = connectionManager.getPublicConnection(destinationAddress);
|
connection = tcpConnectionManager.getPublicConnection(destinationAddress);
|
||||||
if (connection != null && !connection.isClosed()) return connection;
|
if (connection != null && !connection.isClosed()) return connection;
|
||||||
|
|
||||||
connection = establishOutgoingConnection(destinationAddress, senderId, receiverId, false);
|
connection = establishOutgoingConnection(destinationAddress, senderId, receiverId, false);
|
||||||
@@ -146,7 +159,7 @@ public class SocketTCP extends Thread {
|
|||||||
*
|
*
|
||||||
* <p>Cada socket aceito é encaminhado para processamento assíncrono,
|
* <p>Cada socket aceito é encaminhado para processamento assíncrono,
|
||||||
* interpretado como uma {@link TcpConnection}, registrado pelo
|
* interpretado como uma {@link TcpConnection}, registrado pelo
|
||||||
* {@link ConnectionManager} e associado ao receptor adequado.</p>
|
* {@link TcpConnectionManager} e associado ao receptor adequado.</p>
|
||||||
*/
|
*/
|
||||||
private void receive() {
|
private void receive() {
|
||||||
while (running) {
|
while (running) {
|
||||||
@@ -188,7 +201,7 @@ public class SocketTCP extends Thread {
|
|||||||
throw new IllegalArgumentException("Connections to the local host are forbidden.");
|
throw new IllegalArgumentException("Connections to the local host are forbidden.");
|
||||||
}
|
}
|
||||||
|
|
||||||
TcpConnection connection = ConnectionFactory.createConnection(destinationAddress, main.getPort(), sender, receiver, isPrivate);
|
TcpConnection connection = ConnectionFactory.createConnection(destinationAddress, connectionManager.getPort(), sender, receiver, isPrivate);
|
||||||
if (connection == null) return null;
|
if (connection == null) return null;
|
||||||
|
|
||||||
saveConnection(connection);
|
saveConnection(connection);
|
||||||
@@ -229,10 +242,10 @@ public class SocketTCP extends Thread {
|
|||||||
*/
|
*/
|
||||||
private void saveConnection(TcpConnection connection) {
|
private void saveConnection(TcpConnection connection) {
|
||||||
if (connection.isPrivate()) {
|
if (connection.isPrivate()) {
|
||||||
connectionManager.addPrivateConnection(connection);
|
tcpConnectionManager.addPrivateConnection(connection);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
connectionManager.addPublicConnection(connection);
|
tcpConnectionManager.addPublicConnection(connection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,48 +268,21 @@ public class SocketTCP extends Thread {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (connection.getReceiver().equals(main.getIdentifier())) {
|
if (connection.getReceiver().equals(connectionManager.getIdentifier())) {
|
||||||
systemConnectionReceiver(connection);
|
systemConnectionReceiver(connection);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Plugin receiver = findConnectionReceiver(connection);
|
if (pluginManager.handleConnection(connection, connection.getReceiver()))
|
||||||
if (receiver instanceof PrivateConnectionPlugin plugin) {
|
privateConnectionReceiver(connection);
|
||||||
if (notify) {
|
else {
|
||||||
plugin.receivePrivateConnection(connection);
|
|
||||||
}
|
|
||||||
privateConnectionReceiver(connection, plugin);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Localiza o plugin responsável por receber uma conexão privada.
|
|
||||||
*
|
|
||||||
* <p>A busca é feita pelo identificador do destinatário informado na
|
|
||||||
* própria conexão. Caso nenhum plugin correspondente seja encontrado,
|
|
||||||
* uma mensagem de erro é enviada ao peer remoto.</p>
|
|
||||||
*
|
|
||||||
* @param connection conexão privada cujo destinatário será localizado.
|
|
||||||
* @return o plugin com o identificador correspondente ao destinatário,
|
|
||||||
* ou {@code null} se nenhum plugin for encontrado.
|
|
||||||
*/
|
|
||||||
private Plugin findConnectionReceiver(TcpConnection connection) {
|
|
||||||
Plugin receiver = null;
|
|
||||||
for(Plugin plugin : main.getPlugins()) {
|
|
||||||
if (plugin.getIdentifier().equals(connection.getReceiver())) {
|
|
||||||
receiver = plugin;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (receiver == null) {
|
|
||||||
SysInfoMessage.sendSystemInfo(
|
SysInfoMessage.sendSystemInfo(
|
||||||
connection,
|
connection,
|
||||||
SysInfoType.RECEIVER_NOT_FOUND,
|
SysInfoType.RECEIVER_NOT_FOUND,
|
||||||
"This peer does not have the plugin: " + connection.getReceiver()
|
"This peer does not have the plugin: " + connection.getReceiver()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return receiver;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -308,7 +294,7 @@ public class SocketTCP extends Thread {
|
|||||||
* condição de erro.</p>
|
* condição de erro.</p>
|
||||||
*
|
*
|
||||||
* <p>O método também trata timeouts e erros de I/O, removendo a conexão
|
* <p>O método também trata timeouts e erros de I/O, removendo a conexão
|
||||||
* do {@link ConnectionManager} quando ela deixa de ser utilizável.</p>
|
* do {@link TcpConnectionManager} quando ela deixa de ser utilizável.</p>
|
||||||
*
|
*
|
||||||
* @param connection conexão pública da qual as mensagens serão recebidas.
|
* @param connection conexão pública da qual as mensagens serão recebidas.
|
||||||
*/
|
*/
|
||||||
@@ -324,15 +310,13 @@ public class SocketTCP extends Thread {
|
|||||||
SysInfoMessage sysMessage = SysInfoMessage.parseSystemInfo(message);
|
SysInfoMessage sysMessage = SysInfoMessage.parseSystemInfo(message);
|
||||||
|
|
||||||
if (sysMessage == null) {
|
if (sysMessage == null) {
|
||||||
for (Plugin plugin : main.getPlugins()) {
|
pluginManager.handlePublicMessage(message);
|
||||||
plugin.receiveMessage(message);
|
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (sysMessage.getType()) {
|
switch (sysMessage.getType()) {
|
||||||
case CONNECTION_CLOSED, INTERNAL_ERROR -> {
|
case CONNECTION_CLOSED, INTERNAL_ERROR -> {
|
||||||
connectionManager.closeConnection(connection);
|
tcpConnectionManager.closeConnection(connection);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case MESSAGE_REJECTED -> {
|
case MESSAGE_REJECTED -> {
|
||||||
@@ -356,17 +340,17 @@ public class SocketTCP extends Thread {
|
|||||||
"class Message not found."
|
"class Message not found."
|
||||||
);
|
);
|
||||||
logger.log(Level.SEVERE, null, ex);
|
logger.log(Level.SEVERE, null, ex);
|
||||||
connectionManager.closeConnection(connection);
|
tcpConnectionManager.closeConnection(connection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (SocketTimeoutException ex) {
|
catch (SocketTimeoutException ex) {
|
||||||
if (connection.hasTimedOut()) {
|
if (connection.hasTimedOut()) {
|
||||||
connectionManager.closeConnection(connection, "Connection timeout");
|
tcpConnectionManager.closeConnection(connection, "Connection timeout");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (IOException ex) {
|
catch (IOException ex) {
|
||||||
connectionManager.closeConnection(connection);
|
tcpConnectionManager.closeConnection(connection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -381,24 +365,22 @@ public class SocketTCP extends Thread {
|
|||||||
* do plugin e o fechamento da conexão.</p>
|
* do plugin e o fechamento da conexão.</p>
|
||||||
*
|
*
|
||||||
* @param connection conexão privada da qual os dados serão recebidos.
|
* @param connection conexão privada da qual os dados serão recebidos.
|
||||||
* @param plugin plugin responsável pelo processamento dos dados recebidos.
|
|
||||||
*/
|
*/
|
||||||
private void privateConnectionReceiver(TcpConnection connection, Plugin plugin) {
|
private void privateConnectionReceiver(TcpConnection connection) {
|
||||||
if (plugin instanceof PrivateConnectionPlugin privatePlugin) {
|
|
||||||
while (running) {
|
while (running) {
|
||||||
try {
|
try {
|
||||||
byte[] message = connection.receive();
|
byte[] message = connection.receive();
|
||||||
SysInfoMessage sysMessage = SysInfoMessage.parseSystemInfo(message);
|
SysInfoMessage sysMessage = SysInfoMessage.parseSystemInfo(message);
|
||||||
|
|
||||||
if (sysMessage == null) {
|
if (sysMessage == null) {
|
||||||
privatePlugin.receiveBytes(message);
|
pluginManager.handlePrivateMessage(message, connection.getReceiver());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (sysMessage.getType()) {
|
switch (sysMessage.getType()) {
|
||||||
case CONNECTION_CLOSED, INTERNAL_ERROR -> {
|
case CONNECTION_CLOSED, INTERNAL_ERROR -> {
|
||||||
privatePlugin.onSocketClosed(connection);
|
pluginManager.handleDisconnection(connection, connection.getReceiver());
|
||||||
connectionManager.closeConnection(connection);
|
tcpConnectionManager.closeConnection(connection);
|
||||||
}
|
}
|
||||||
default -> {
|
default -> {
|
||||||
continue;
|
continue;
|
||||||
@@ -407,13 +389,12 @@ public class SocketTCP extends Thread {
|
|||||||
}
|
}
|
||||||
catch (SocketTimeoutException ex) {
|
catch (SocketTimeoutException ex) {
|
||||||
if (connection.hasTimedOut()) {
|
if (connection.hasTimedOut()) {
|
||||||
connectionManager.closeConnection(connection, "Connection timeout");
|
tcpConnectionManager.closeConnection(connection, "Connection timeout");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (IOException ex) {
|
catch (IOException ex) {
|
||||||
connectionManager.closeConnection(connection);
|
tcpConnectionManager.closeConnection(connection);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -445,7 +426,7 @@ public class SocketTCP extends Thread {
|
|||||||
if (connection.hasTimedOut()) return;
|
if (connection.hasTimedOut()) return;
|
||||||
}
|
}
|
||||||
catch (IOException ex) {
|
catch (IOException ex) {
|
||||||
connectionManager.closeConnection(connection);
|
tcpConnectionManager.closeConnection(connection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -454,13 +435,13 @@ public class SocketTCP extends Thread {
|
|||||||
* Encerra uma conexão TCP e registra o motivo informado.
|
* Encerra uma conexão TCP e registra o motivo informado.
|
||||||
*
|
*
|
||||||
* <p>Quando nenhuma descrição é fornecida, é utilizado um motivo padrão.
|
* <p>Quando nenhuma descrição é fornecida, é utilizado um motivo padrão.
|
||||||
* O fechamento efetivo da conexão é delegado ao {@link ConnectionManager}.</p>
|
* O fechamento efetivo da conexão é delegado ao {@link TcpConnectionManager}.</p>
|
||||||
*
|
*
|
||||||
* @param connection conexão que será encerrada.
|
* @param connection conexão que será encerrada.
|
||||||
* @param description motivo do encerramento; pode ser {@code null}.
|
* @param description motivo do encerramento; pode ser {@code null}.
|
||||||
*/
|
*/
|
||||||
public void disconnect(TcpConnection connection, String description) {
|
public void disconnect(TcpConnection connection, String description) {
|
||||||
connectionManager.closeConnection(
|
tcpConnectionManager.closeConnection(
|
||||||
connection,
|
connection,
|
||||||
Objects.requireNonNullElse(description, "No reason provided")
|
Objects.requireNonNullElse(description, "No reason provided")
|
||||||
);
|
);
|
||||||
@@ -493,7 +474,7 @@ public class SocketTCP extends Thread {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
connectionManager.closeAllConnections("The peer must have closed the application or changed ports");
|
tcpConnectionManager.closeAllConnections("The peer must have closed the application or changed ports");
|
||||||
|
|
||||||
connectionExecutor.shutdownNow();
|
connectionExecutor.shutdownNow();
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -27,7 +27,7 @@ import java.util.stream.Collectors;
|
|||||||
* peers ativos para encerrar conexões associadas a peers que deixaram de
|
* peers ativos para encerrar conexões associadas a peers que deixaram de
|
||||||
* estar disponíveis.</p>
|
* estar disponíveis.</p>
|
||||||
*/
|
*/
|
||||||
class ConnectionManager implements PeerListener {
|
class TcpConnectionManager implements PeerListener {
|
||||||
private final Logger logger;
|
private final Logger logger;
|
||||||
private final Map<InetAddress, TcpConnection> publicConnections;
|
private final Map<InetAddress, TcpConnection> publicConnections;
|
||||||
private final Map<InetAddress, List<TcpConnection>> privateConnections;
|
private final Map<InetAddress, List<TcpConnection>> privateConnections;
|
||||||
@@ -35,7 +35,7 @@ class ConnectionManager implements PeerListener {
|
|||||||
/**
|
/**
|
||||||
* Cria um gerenciador de conexões TCP vazio.
|
* Cria um gerenciador de conexões TCP vazio.
|
||||||
*/
|
*/
|
||||||
public ConnectionManager() {
|
public TcpConnectionManager() {
|
||||||
publicConnections = new ConcurrentHashMap<>();
|
publicConnections = new ConcurrentHashMap<>();
|
||||||
privateConnections = new ConcurrentHashMap<>();
|
privateConnections = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
@@ -14,6 +14,8 @@ import java.net.*;
|
|||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import pitiupi.control.ConnectionManager;
|
||||||
|
import pitiupi.control.PluginManager;
|
||||||
import pitiupi.net.HeartbeatMessage;
|
import pitiupi.net.HeartbeatMessage;
|
||||||
import pitiupi.net.Message;
|
import pitiupi.net.Message;
|
||||||
import pitiupi.plugin.Plugin;
|
import pitiupi.plugin.Plugin;
|
||||||
@@ -37,7 +39,10 @@ public class SocketUDP extends Thread {
|
|||||||
private MulticastSocket multicastSocket;
|
private MulticastSocket multicastSocket;
|
||||||
|
|
||||||
private InetAddress address;
|
private InetAddress address;
|
||||||
private MainWindow main;
|
|
||||||
|
private ConnectionManager connectionManager;
|
||||||
|
private PluginManager pluginManager;
|
||||||
|
|
||||||
private volatile boolean running = true;
|
private volatile boolean running = true;
|
||||||
public final static String INET_ADDR = "224.0.0.3";
|
public final static String INET_ADDR = "224.0.0.3";
|
||||||
|
|
||||||
@@ -47,22 +52,26 @@ public class SocketUDP extends Thread {
|
|||||||
* <p>O socket é associado à porta da aplicação e ingressa no grupo
|
* <p>O socket é associado à porta da aplicação e ingressa no grupo
|
||||||
* multicast configurado.</p>
|
* multicast configurado.</p>
|
||||||
*
|
*
|
||||||
* @param main janela principal da aplicação.
|
* @param connectionManager interface que gerencia toda conexão da aplicação.
|
||||||
|
* @param pluginManager interface que gerencia os plugins da conexão.
|
||||||
*/
|
*/
|
||||||
public SocketUDP(MainWindow main) {
|
public SocketUDP(ConnectionManager connectionManager, PluginManager pluginManager) {
|
||||||
this.main = main;
|
this.connectionManager = connectionManager;
|
||||||
|
this.pluginManager = pluginManager;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.address = InetAddress.getByName(SocketUDP.INET_ADDR);
|
this.address = InetAddress.getByName(SocketUDP.INET_ADDR);
|
||||||
} catch (UnknownHostException ex) {
|
|
||||||
System.getLogger(SocketUDP.class.getName()).log(System.Logger.Level.ERROR, (String) null, ex);
|
multicastSocket = new MulticastSocket(connectionManager.getPort());
|
||||||
}
|
|
||||||
try {
|
|
||||||
multicastSocket = new MulticastSocket(this.main.getPort());
|
|
||||||
multicastSocket.setSendBufferSize(256000);
|
multicastSocket.setSendBufferSize(256000);
|
||||||
multicastSocket.setReceiveBufferSize(256000);
|
multicastSocket.setReceiveBufferSize(256000);
|
||||||
multicastSocket.setReuseAddress(true);
|
multicastSocket.setReuseAddress(true);
|
||||||
multicastSocket.joinGroup(address);
|
multicastSocket.joinGroup(address);
|
||||||
} catch (IOException ex) {
|
}
|
||||||
|
catch (UnknownHostException ex) {
|
||||||
|
System.getLogger(SocketUDP.class.getName()).log(System.Logger.Level.ERROR, (String) null, ex);
|
||||||
|
}
|
||||||
|
catch (IOException ex) {
|
||||||
System.out.println("There is no socket connection. Sorry.");
|
System.out.println("There is no socket connection. Sorry.");
|
||||||
System.out.println(ex);
|
System.out.println(ex);
|
||||||
}
|
}
|
||||||
@@ -71,22 +80,22 @@ public class SocketUDP extends Thread {
|
|||||||
/**
|
/**
|
||||||
* Envia uma mensagem para o grupo multicast da aplicação.
|
* Envia uma mensagem para o grupo multicast da aplicação.
|
||||||
*
|
*
|
||||||
* @param msg mensagem serializada a ser enviada.
|
* @param msg mensagem a ser enviada.
|
||||||
* @throws IOException caso ocorra um erro durante o envio.
|
* @throws IOException caso ocorra um erro durante o envio.
|
||||||
*/
|
*/
|
||||||
public void sendMulticast(byte[] msg) throws IOException {
|
public void sendMulticast(Message msg) throws IOException {
|
||||||
send(msg, this.address);
|
send(msg.toByteArray(), this.address);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Envia uma mensagem diretamente para um peer utilizando UDP.
|
* Envia uma mensagem diretamente para um peer utilizando UDP.
|
||||||
*
|
*
|
||||||
* @param msg mensagem serializada a ser enviada.
|
* @param msg mensagem a ser enviada.
|
||||||
* @param destinationAddress endereço IP do peer destinatário.
|
* @param destinationAddress endereço IP do peer destinatário.
|
||||||
* @throws IOException caso ocorra um erro durante o envio.
|
* @throws IOException caso ocorra um erro durante o envio.
|
||||||
*/
|
*/
|
||||||
public void sendUnicast(byte[] msg, InetAddress destinationAddress) throws IOException {
|
public void sendUnicast(Message msg, InetAddress destinationAddress) throws IOException {
|
||||||
send(msg, destinationAddress);
|
send(msg.toByteArray(), destinationAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -98,7 +107,7 @@ public class SocketUDP extends Thread {
|
|||||||
*/
|
*/
|
||||||
private void send(byte[] msg, InetAddress destinationAddress) throws IOException {
|
private void send(byte[] msg, InetAddress destinationAddress) throws IOException {
|
||||||
DatagramPacket msgPacket;
|
DatagramPacket msgPacket;
|
||||||
msgPacket = new DatagramPacket(msg, msg.length, destinationAddress, this.main.getPort());
|
msgPacket = new DatagramPacket(msg, msg.length, destinationAddress, connectionManager.getPort());
|
||||||
multicastSocket.send(msgPacket);
|
multicastSocket.send(msgPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,7 +154,7 @@ public class SocketUDP extends Thread {
|
|||||||
}
|
}
|
||||||
HeartbeatMessage heartbeat = tryParseHeartbeat(msgPacket.getData());
|
HeartbeatMessage heartbeat = tryParseHeartbeat(msgPacket.getData());
|
||||||
if (heartbeat != null) {
|
if (heartbeat != null) {
|
||||||
main.getHeartbeatManager().receiveHeartbeat(heartbeat, msgPacket.getAddress());
|
connectionManager.receiveHeartbeat(heartbeat, msgPacket.getAddress());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,10 +163,8 @@ public class SocketUDP extends Thread {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Plugin plugin : main.getPlugins()) {
|
|
||||||
System.out.println(msgPacket.getAddress().toString());
|
System.out.println(msgPacket.getAddress().toString());
|
||||||
plugin.receiveMessage(message);
|
pluginManager.handlePublicMessage(message);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user