Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
725c809436
8 changed files with 163 additions and 82 deletions
|
@ -2,7 +2,6 @@ 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;
|
||||
|
@ -36,12 +35,10 @@ public class MainApp extends Application {
|
|||
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);
|
||||
(ipAddr, data) -> System.out.println("User detected at address : " + ipAddr.toString()),
|
||||
Throwable::printStackTrace);
|
||||
NetDiscoverer.startDiscoveryListening("Yohan", null, Throwable::printStackTrace);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package fr.insa.clavardator.network;
|
||||
|
||||
import fr.insa.clavardator.util.ErrorHandler;
|
||||
import fr.insa.clavardator.util.ErrorCallback;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -26,28 +26,41 @@ public class NetDiscoverer {
|
|||
/**
|
||||
* Discovers all active users in the network, and call the callback for each of them
|
||||
*
|
||||
* @param callback function to call when a new user is discovered
|
||||
* @param broadcastMessage The message to send as broadcast
|
||||
* @param callback function to call when a new user is discovered
|
||||
* @param errorCallback function to call on error
|
||||
*/
|
||||
public static void discoverActiveUsers(String broadcastMessage, ResponseReceivedCallback callback) {
|
||||
ResponseListener receiver = new ResponseListener(callback);
|
||||
BroadcastSender sender = new BroadcastSender(broadcastMessage);
|
||||
public static void discoverActiveUsers(String broadcastMessage, ResponseReceivedCallback callback, ErrorCallback errorCallback) {
|
||||
ResponseListener receiver = new ResponseListener(callback, errorCallback);
|
||||
BroadcastSender sender = new BroadcastSender(broadcastMessage, errorCallback);
|
||||
receiver.start();
|
||||
sender.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts to listen for discovery broadcasts and answers them
|
||||
*
|
||||
* @param responseMessage The message to send in response to broadcasts
|
||||
* @param onBroadcastReceived The function to call on success
|
||||
* @param errorCallback The function to call on error
|
||||
*/
|
||||
public static void startDiscoveryListening(String responseMessage, @Nullable BroadcastReceivedCallback onBroadcastReceived) {
|
||||
public static void startDiscoveryListening(String responseMessage, @Nullable BroadcastReceivedCallback onBroadcastReceived, @Nullable ErrorCallback errorCallback) {
|
||||
BroadcastListener listener = new BroadcastListener((ipAddr, data) -> {
|
||||
if (onBroadcastReceived != null)
|
||||
onBroadcastReceived.onBroadcastReceived(ipAddr, data);
|
||||
new ResponseSender(ipAddr, responseMessage).start();
|
||||
}
|
||||
);
|
||||
ResponseSender sender = new ResponseSender(ipAddr, responseMessage, errorCallback);
|
||||
sender.start();
|
||||
}, e -> {
|
||||
if (errorCallback != null)
|
||||
errorCallback.onError(e);
|
||||
});
|
||||
|
||||
listener.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop network discovery and listening
|
||||
*/
|
||||
public static void stopDiscovery() {
|
||||
shouldStop = true;
|
||||
if (broadcastListener != null)
|
||||
|
@ -58,15 +71,18 @@ public class NetDiscoverer {
|
|||
|
||||
|
||||
private static class BroadcastSender extends Thread {
|
||||
String broadcastMessage;
|
||||
private final String broadcastMessage;
|
||||
private final ErrorCallback errorCallback;
|
||||
|
||||
/**
|
||||
* Constructs and starts a thread that sends a broadcast over the network
|
||||
* Constructs a thread that sends a broadcast over the network
|
||||
*
|
||||
* @param broadcastMessage The message to send
|
||||
* @param errorCallback The function to call on error
|
||||
*/
|
||||
public BroadcastSender(String broadcastMessage) {
|
||||
public BroadcastSender(String broadcastMessage, ErrorCallback errorCallback) {
|
||||
this.broadcastMessage = broadcastMessage;
|
||||
this.errorCallback = errorCallback;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -81,22 +97,30 @@ public class NetDiscoverer {
|
|||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
ErrorHandler.getInstance().notifyError(e);
|
||||
errorCallback.onError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class BroadcastListener extends Thread {
|
||||
BroadcastReceivedCallback callback;
|
||||
private final BroadcastReceivedCallback callback;
|
||||
private final ErrorCallback errorCallback;
|
||||
|
||||
public BroadcastListener(BroadcastReceivedCallback callback) {
|
||||
/**
|
||||
* Constructs a thread that sends a broadcast over the network, using all available interfaces
|
||||
*
|
||||
* @param callback The function to call on success
|
||||
* @param errorCallback The function to call on error
|
||||
*/
|
||||
public BroadcastListener(BroadcastReceivedCallback callback, ErrorCallback errorCallback) {
|
||||
this.callback = callback;
|
||||
this.errorCallback = errorCallback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
while (!shouldStop) {
|
||||
try {
|
||||
try {
|
||||
while (!shouldStop) {
|
||||
broadcastListener = new DatagramSocket(null);
|
||||
broadcastListener.setOption(StandardSocketOptions.SO_REUSEPORT, true);
|
||||
broadcastListener.setOption(StandardSocketOptions.SO_REUSEADDR, true);
|
||||
|
@ -108,27 +132,31 @@ public class NetDiscoverer {
|
|||
broadcastListener.receive(receivedPacket);
|
||||
// System.out.println("broadcast received from " + receivedPacket.getAddress().toString());
|
||||
callback.onBroadcastReceived(receivedPacket.getAddress(), new String(receivedPacket.getData()));
|
||||
} catch (IOException e) {
|
||||
if (!shouldStop) {
|
||||
ErrorHandler.getInstance().notifyError(e);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
if (!shouldStop) {
|
||||
errorCallback.onError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class ResponseSender extends Thread {
|
||||
String message;
|
||||
InetAddress address;
|
||||
private final String message;
|
||||
private final InetAddress address;
|
||||
private final ErrorCallback errorCallback;
|
||||
|
||||
/**
|
||||
* Constructs and starts a thread that sends a broadcast over the network
|
||||
* Constructs a thread that sends a UDP response
|
||||
*
|
||||
* @param message The message to send
|
||||
* @param address The address of the remote host
|
||||
* @param message The message to send
|
||||
* @param errorCallback The function to call on error
|
||||
*/
|
||||
public ResponseSender(InetAddress address, String message) {
|
||||
public ResponseSender(InetAddress address, String message, ErrorCallback errorCallback) {
|
||||
this.address = address;
|
||||
this.message = message;
|
||||
this.errorCallback = errorCallback;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -139,22 +167,30 @@ public class NetDiscoverer {
|
|||
responseSocket.send(new DatagramPacket(buf, buf.length, address, RESPONSE_PORT));
|
||||
// System.out.println("Response sent to " + address.toString());
|
||||
} catch (IOException e) {
|
||||
ErrorHandler.getInstance().notifyError(e);
|
||||
errorCallback.onError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class ResponseListener extends Thread {
|
||||
ResponseReceivedCallback callback;
|
||||
private final ResponseReceivedCallback callback;
|
||||
private final ErrorCallback errorCallback;
|
||||
|
||||
public ResponseListener(ResponseReceivedCallback callback) {
|
||||
/**
|
||||
* Constructs a thread that receives all UDP responses, until stopDiscovery() is called
|
||||
*
|
||||
* @param callback The function to call on success
|
||||
* @param errorCallback The function to call on error
|
||||
*/
|
||||
public ResponseListener(ResponseReceivedCallback callback, ErrorCallback errorCallback) {
|
||||
this.callback = callback;
|
||||
this.errorCallback = errorCallback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
while (!shouldStop) {
|
||||
try {
|
||||
try {
|
||||
while (!shouldStop) {
|
||||
responseListener = new DatagramSocket(null);
|
||||
responseListener.setOption(StandardSocketOptions.SO_REUSEPORT, true);
|
||||
responseListener.setOption(StandardSocketOptions.SO_REUSEADDR, true);
|
||||
|
@ -165,10 +201,10 @@ public class NetDiscoverer {
|
|||
responseListener.receive(receivedPacket);
|
||||
// System.out.println("response received from " + receivedPacket.getAddress().toString());
|
||||
callback.onResponseReceived(receivedPacket.getAddress(), new String(receivedPacket.getData()));
|
||||
} catch (IOException e) {
|
||||
if (!shouldStop) {
|
||||
ErrorHandler.getInstance().notifyError(e);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
if (!shouldStop) {
|
||||
errorCallback.onError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -177,7 +213,7 @@ public class NetDiscoverer {
|
|||
|
||||
static List<InetAddress> listAllBroadcastAddresses() throws SocketException {
|
||||
List<InetAddress> broadcastList = new ArrayList<>();
|
||||
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
|
||||
final Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
|
||||
|
||||
while (interfaces.hasMoreElements()) {
|
||||
NetworkInterface networkInterface = interfaces.nextElement();
|
||||
|
@ -192,12 +228,11 @@ public class NetDiscoverer {
|
|||
}
|
||||
|
||||
|
||||
public interface ResponseReceivedCallback {
|
||||
void onResponseReceived(InetAddress ipAddr, String data);
|
||||
}
|
||||
|
||||
private interface BroadcastReceivedCallback {
|
||||
void onBroadcastReceived(InetAddress ipAddr, String data);
|
||||
}
|
||||
|
||||
public interface ResponseReceivedCallback {
|
||||
void onResponseReceived(InetAddress ipAddr, String data);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
package fr.insa.clavardator.network;
|
||||
|
||||
import fr.insa.clavardator.chat.Message;
|
||||
import fr.insa.clavardator.util.ErrorHandler;
|
||||
import fr.insa.clavardator.util.ErrorCallback;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.net.InetAddress;
|
||||
|
@ -12,76 +15,107 @@ import java.net.Socket;
|
|||
public class PeerConnection {
|
||||
public static final short PORT = 31598;
|
||||
|
||||
private Socket socket;
|
||||
private final ObjectOutputStream outputStream;
|
||||
private final ObjectInputStream inputStream;
|
||||
|
||||
public PeerConnection(InetAddress ipAddr) {
|
||||
try {
|
||||
socket = new Socket(ipAddr, PORT);
|
||||
} catch (IOException e) {
|
||||
ErrorHandler.getInstance().notifyError(e);
|
||||
}
|
||||
public PeerConnection(InetAddress ipAddr) throws IOException {
|
||||
Socket socket = new Socket(ipAddr, PORT);
|
||||
outputStream = new ObjectOutputStream(socket.getOutputStream());
|
||||
inputStream = new ObjectInputStream(socket.getInputStream());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param message
|
||||
* @param callback
|
||||
* Sends a message to the peer
|
||||
*
|
||||
* @param message The message to send
|
||||
* @param callback The function to call on success
|
||||
* @param errorCallback The function to call on error
|
||||
*/
|
||||
public void sendMessage(Message message, MessageSentCallback callback) {
|
||||
Sender sender = new Sender(message, callback);
|
||||
public void sendMessage(Message message, MessageSentCallback callback, ErrorCallback errorCallback) {
|
||||
Sender sender = new Sender(message, callback, errorCallback);
|
||||
sender.start();
|
||||
}
|
||||
|
||||
public void receiveMessage(MessageReceivedCallback callback) {
|
||||
Receiver receiver = new Receiver(callback);
|
||||
/**
|
||||
* Receives a message from the peer
|
||||
*
|
||||
* @param callback The function to call on success
|
||||
* @param errorCallback The function to call on error
|
||||
*/
|
||||
public void receiveMessage(MessageReceivedCallback callback, ErrorCallback errorCallback) {
|
||||
Receiver receiver = new Receiver(callback, errorCallback);
|
||||
receiver.start();
|
||||
}
|
||||
|
||||
|
||||
private class Sender extends Thread {
|
||||
Serializable message;
|
||||
MessageSentCallback callback;
|
||||
private final Serializable message;
|
||||
private final MessageSentCallback callback;
|
||||
private final ErrorCallback errorCallback;
|
||||
|
||||
/**
|
||||
* Constructs and starts a thread that sends a message using the socket of the outer class
|
||||
* @param messsage The message to send
|
||||
* @param callback The function to call once finished
|
||||
* Constructs a thread that sends a message using the socket of the outer class
|
||||
*
|
||||
* @param messsage The message to send
|
||||
* @param callback The function to call on success
|
||||
* @param errorCallback The function to call on error
|
||||
*/
|
||||
public Sender(Serializable messsage, MessageSentCallback callback) {
|
||||
public Sender(Serializable messsage, @Nullable MessageSentCallback callback, @Nullable ErrorCallback errorCallback) {
|
||||
this.message = messsage;
|
||||
this.callback = callback;
|
||||
this.errorCallback = errorCallback;
|
||||
}
|
||||
|
||||
@Override
|
||||
synchronized public void run() {
|
||||
try {
|
||||
// TODO: store the oos in Peer connection?
|
||||
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
|
||||
oos.writeObject(message);
|
||||
outputStream.writeObject(message);
|
||||
if (callback != null)
|
||||
callback.onMessageSent();
|
||||
} catch (IOException e) {
|
||||
ErrorHandler.getInstance().notifyError(e);
|
||||
if (errorCallback != null)
|
||||
errorCallback.onError(e);
|
||||
}
|
||||
callback.onMessageSent();
|
||||
}
|
||||
}
|
||||
|
||||
private class Receiver extends Thread {
|
||||
MessageReceivedCallback callback;
|
||||
private final MessageReceivedCallback callback;
|
||||
private final ErrorCallback errorCallback;
|
||||
|
||||
public Receiver(MessageReceivedCallback callback) {
|
||||
/**
|
||||
* Constructs a thread that receives a message using the socket of the outer class
|
||||
*
|
||||
* @param callback The function to call on success
|
||||
* @param errorCallback The function to call on error
|
||||
*/
|
||||
public Receiver(@NotNull MessageReceivedCallback callback, @Nullable ErrorCallback errorCallback) {
|
||||
this.callback = callback;
|
||||
this.errorCallback = errorCallback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
//TODO
|
||||
// callback.onMessageReceived();
|
||||
try {
|
||||
Object msg = inputStream.readObject();
|
||||
if (msg.getClass().isInstance(Message.class)) {
|
||||
callback.onMessageReceived((Message) msg);
|
||||
} else {
|
||||
if (errorCallback != null)
|
||||
errorCallback.onError(new ClassCastException("The message received is not a valid Message object"));
|
||||
}
|
||||
} catch (IOException | ClassNotFoundException e) {
|
||||
if (errorCallback != null)
|
||||
errorCallback.onError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public interface MessageReceivedCallback {
|
||||
public interface MessageReceivedCallback {
|
||||
void onMessageReceived(Message msg);
|
||||
}
|
||||
|
||||
public interface MessageSentCallback {
|
||||
void onMessageSent();
|
||||
}
|
||||
|
|
|
@ -11,9 +11,9 @@ import javafx.fxml.FXML;
|
|||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.control.ListView;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.URL;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.ResourceBundle;
|
||||
|
@ -65,7 +65,7 @@ public class UserListController implements Initializable {
|
|||
new PeerUser("Dodo1"),
|
||||
new ActiveUser("Coucou2", InetAddress.getLocalHost())
|
||||
);
|
||||
} catch (UnknownHostException e) {
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (activeList != null) {
|
||||
|
|
|
@ -3,6 +3,7 @@ package fr.insa.clavardator.users;
|
|||
import fr.insa.clavardator.chat.Message;
|
||||
import fr.insa.clavardator.network.PeerConnection;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
|
||||
|
||||
|
@ -10,7 +11,7 @@ public class ActiveUser extends PeerUser {
|
|||
|
||||
private transient PeerConnection connection;
|
||||
|
||||
public ActiveUser(String username, InetAddress ipAddr) {
|
||||
public ActiveUser(String username, InetAddress ipAddr) throws IOException {
|
||||
super(username);
|
||||
connection = new PeerConnection(ipAddr);
|
||||
}
|
||||
|
@ -19,6 +20,7 @@ public class ActiveUser extends PeerUser {
|
|||
* @param message
|
||||
*/
|
||||
public void sendMessage(Message message) {
|
||||
// connection.sendMessage(message);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2,9 +2,11 @@ package fr.insa.clavardator.users;
|
|||
|
||||
import fr.insa.clavardator.db.DatabaseController;
|
||||
import fr.insa.clavardator.network.NetDiscoverer;
|
||||
import fr.insa.clavardator.util.ErrorCallback;
|
||||
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
|
@ -47,12 +49,17 @@ public class UserList {
|
|||
/**
|
||||
*
|
||||
*/
|
||||
public void discoverActiveUsers() {
|
||||
public void discoverActiveUsers(ErrorCallback errorCallback) {
|
||||
NetDiscoverer.discoverActiveUsers("CLAVARDATOR_BROADCAST", (ipAddr, data) -> {
|
||||
ActiveUser newUser = new ActiveUser("", ipAddr); // TODO find username
|
||||
ActiveUser newUser = null;
|
||||
try {
|
||||
newUser = new ActiveUser("", ipAddr); // TODO find username
|
||||
} catch (IOException e) {
|
||||
errorCallback.onError(e);
|
||||
}
|
||||
activeUsers.add(newUser);
|
||||
pcs.firePropertyChange("activeUsers", null, newUser);
|
||||
});
|
||||
}, errorCallback);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
package fr.insa.clavardator.util;
|
||||
|
||||
public interface ErrorCallback {
|
||||
void onError(Exception e);
|
||||
}
|
|
@ -3,6 +3,7 @@ package fr.insa.clavardator.util;
|
|||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
|
||||
@Deprecated
|
||||
public class ErrorHandler {
|
||||
private ErrorHandler() {}
|
||||
|
||||
|
|
Loading…
Reference in a new issue