diff --git a/build.gradle b/build.gradle index 41c4f46..89b0a93 100644 --- a/build.gradle +++ b/build.gradle @@ -17,6 +17,7 @@ javafx { } dependencies { + implementation 'org.jetbrains:annotations:20.1.0' runtimeOnly "org.openjfx:javafx-graphics:$javafx.version:win" runtimeOnly "org.openjfx:javafx-graphics:$javafx.version:linux" runtimeOnly "org.openjfx:javafx-graphics:$javafx.version:mac" diff --git a/src/main/java/fr/insa/clavardator/MainApp.java b/src/main/java/fr/insa/clavardator/MainApp.java index da3b816..8181676 100644 --- a/src/main/java/fr/insa/clavardator/MainApp.java +++ b/src/main/java/fr/insa/clavardator/MainApp.java @@ -1,6 +1,8 @@ package fr.insa.clavardator; +import fr.insa.clavardator.network.NetDiscoverer; import fr.insa.clavardator.ui.MainController; +import fr.insa.clavardator.util.ErrorHandler; import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.scene.Parent; @@ -32,6 +34,19 @@ public class MainApp extends Application { stage.setMinWidth(800); stage.setMaximized(true); stage.show(); + + // Network discovery test + ErrorHandler.getInstance().addObserver(evt -> ((Exception)evt.getNewValue()).printStackTrace()); + + NetDiscoverer.discoverActiveUsers("Broadcast", + (ipAddr, data) -> System.out.println("User detected at address : " + ipAddr.toString()) + ); + NetDiscoverer.startDiscoveryListening("Yohan", null); } + @Override + public void stop() throws Exception { + NetDiscoverer.stopDiscovery(); + super.stop(); + } } \ No newline at end of file diff --git a/src/main/java/fr/insa/clavardator/network/NetDiscoverer.java b/src/main/java/fr/insa/clavardator/network/NetDiscoverer.java index 8a55295..57d9ec5 100644 --- a/src/main/java/fr/insa/clavardator/network/NetDiscoverer.java +++ b/src/main/java/fr/insa/clavardator/network/NetDiscoverer.java @@ -1,6 +1,7 @@ package fr.insa.clavardator.network; import fr.insa.clavardator.util.ErrorHandler; +import org.jetbrains.annotations.Nullable; import java.io.IOException; import java.net.*; @@ -12,8 +13,12 @@ import java.util.Objects; public class NetDiscoverer { private static final short DISCOVERY_PORT = 31593; private static final short RESPONSE_PORT = 31594; - public static final int BROADCAST_BUFFER_SIZE = 50; - public static final int RESPONSE_BUFFER_SIZE = 50; + private static final int BROADCAST_BUFFER_SIZE = 50; + private static final int RESPONSE_BUFFER_SIZE = 50; + + private static DatagramSocket broadcastListener; + private static DatagramSocket responseListener; + private static boolean shouldStop = false; private NetDiscoverer() { } @@ -23,9 +28,9 @@ public class NetDiscoverer { * * @param callback function to call when a new user is discovered */ - public static void discoverActiveUsers(ResponseReceivedCallback callback) { + public static void discoverActiveUsers(String broadcastMessage, ResponseReceivedCallback callback) { ResponseListener receiver = new ResponseListener(callback); - BroadcastSender sender = new BroadcastSender("USER_DISCOVERY_BROADCAST"); + BroadcastSender sender = new BroadcastSender(broadcastMessage); receiver.start(); sender.start(); } @@ -33,13 +38,24 @@ public class NetDiscoverer { /** * Starts to listen for discovery broadcasts and answers them */ - public static void startDiscoveryListening() { - BroadcastListener listener = new BroadcastListener( - (ipAddr, data) -> new ResponseSender(ipAddr, "USER_DISCOVERY_RESPONSE").start() + public static void startDiscoveryListening(String responseMessage, @Nullable BroadcastReceivedCallback onBroadcastReceived) { + BroadcastListener listener = new BroadcastListener((ipAddr, data) -> { + if (onBroadcastReceived != null) + onBroadcastReceived.onBroadcastReceived(ipAddr, data); + new ResponseSender(ipAddr, responseMessage).start(); + } ); listener.start(); } + public static void stopDiscovery() { + shouldStop = true; + if (broadcastListener != null) + broadcastListener.close(); + if (responseListener != null) + responseListener.close(); + } + private static class BroadcastSender extends Thread { String broadcastMessage; @@ -79,22 +95,23 @@ public class NetDiscoverer { @Override public void run() { - while (true) { // TODO: add a stop condition + while (!shouldStop) { try { - DatagramSocket listener = new DatagramSocket(null); - listener.setOption(StandardSocketOptions.SO_REUSEPORT, true); - listener.setOption(StandardSocketOptions.SO_REUSEADDR, true); - listener.bind(new InetSocketAddress((InetAddress) null, DISCOVERY_PORT)); + broadcastListener = new DatagramSocket(null); + broadcastListener.setOption(StandardSocketOptions.SO_REUSEPORT, true); + broadcastListener.setOption(StandardSocketOptions.SO_REUSEADDR, true); + broadcastListener.bind(new InetSocketAddress((InetAddress) null, DISCOVERY_PORT)); byte[] buffer = new byte[BROADCAST_BUFFER_SIZE]; DatagramPacket receivedPacket = new DatagramPacket(buffer, BROADCAST_BUFFER_SIZE); - listener.receive(receivedPacket); + broadcastListener.receive(receivedPacket); // System.out.println("broadcast received from " + receivedPacket.getAddress().toString()); callback.onBroadcastReceived(receivedPacket.getAddress(), new String(receivedPacket.getData())); } catch (IOException e) { - e.printStackTrace(); - ErrorHandler.getInstance().notifyError(e); + if (!shouldStop) { + ErrorHandler.getInstance().notifyError(e); + } } } } @@ -136,20 +153,22 @@ public class NetDiscoverer { @Override public void run() { - while (true) { // TODO: add a stop condition + while (!shouldStop) { try { - DatagramSocket listener = new DatagramSocket(null); - listener.setOption(StandardSocketOptions.SO_REUSEPORT, true); - listener.setOption(StandardSocketOptions.SO_REUSEADDR, true); - listener.bind(new InetSocketAddress((InetAddress) null, RESPONSE_PORT)); + responseListener = new DatagramSocket(null); + responseListener.setOption(StandardSocketOptions.SO_REUSEPORT, true); + responseListener.setOption(StandardSocketOptions.SO_REUSEADDR, true); + responseListener.bind(new InetSocketAddress((InetAddress) null, RESPONSE_PORT)); byte[] buffer = new byte[RESPONSE_BUFFER_SIZE]; DatagramPacket receivedPacket = new DatagramPacket(buffer, RESPONSE_BUFFER_SIZE); - listener.receive(receivedPacket); + responseListener.receive(receivedPacket); // System.out.println("response received from " + receivedPacket.getAddress().toString()); callback.onResponseReceived(receivedPacket.getAddress(), new String(receivedPacket.getData())); } catch (IOException e) { - ErrorHandler.getInstance().notifyError(e); + if (!shouldStop) { + ErrorHandler.getInstance().notifyError(e); + } } } } diff --git a/src/main/java/fr/insa/clavardator/users/User.java b/src/main/java/fr/insa/clavardator/users/User.java index 172c2ee..a2609a3 100644 --- a/src/main/java/fr/insa/clavardator/users/User.java +++ b/src/main/java/fr/insa/clavardator/users/User.java @@ -1,10 +1,12 @@ package fr.insa.clavardator.users; +import org.jetbrains.annotations.NotNull; + import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.io.Serializable; -public class User implements Serializable { +public class User implements Serializable, Comparable { protected String username; // Make this class observable @@ -28,4 +30,8 @@ public class User implements Serializable { } + @Override + public int compareTo(@NotNull User o) { + return username.compareTo(o.username); + } } diff --git a/src/main/java/fr/insa/clavardator/users/UserList.java b/src/main/java/fr/insa/clavardator/users/UserList.java index 21048fe..a965e6a 100644 --- a/src/main/java/fr/insa/clavardator/users/UserList.java +++ b/src/main/java/fr/insa/clavardator/users/UserList.java @@ -48,7 +48,7 @@ public class UserList { * */ public void discoverActiveUsers() { - NetDiscoverer.discoverActiveUsers((ipAddr, data) -> { + NetDiscoverer.discoverActiveUsers("CLAVARDATOR_BROADCAST", (ipAddr, data) -> { ActiveUser newUser = new ActiveUser("", ipAddr); // TODO find username activeUsers.add(newUser); pcs.firePropertyChange("activeUsers", null, newUser);