Implement network discovery methods (working)
This commit is contained in:
parent
dd38c059a7
commit
ab5b058498
2 changed files with 139 additions and 42 deletions
|
@ -1,84 +1,184 @@
|
||||||
package fr.insa.clavardator.network;
|
package fr.insa.clavardator.network;
|
||||||
|
|
||||||
import fr.insa.clavardator.users.ActiveUser;
|
|
||||||
import fr.insa.clavardator.util.ErrorHandler;
|
import fr.insa.clavardator.util.ErrorHandler;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.DatagramPacket;
|
import java.net.*;
|
||||||
import java.net.DatagramSocket;
|
import java.util.ArrayList;
|
||||||
import java.net.InetAddress;
|
import java.util.Enumeration;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public class NetDiscoverer {
|
public class NetDiscoverer {
|
||||||
private static final short DISCOVERY_PORT = 31596;
|
private static final short DISCOVERY_PORT = 31593;
|
||||||
private static final short RESPONSE_PORT = 31597;
|
private static final short RESPONSE_PORT = 31594;
|
||||||
|
public static final int BROADCAST_BUFFER_SIZE = 50;
|
||||||
|
public static final int RESPONSE_BUFFER_SIZE = 50;
|
||||||
|
|
||||||
public NetDiscoverer() {}
|
private NetDiscoverer() {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param message
|
* Discovers all active users in the network, and call the callback for each of them
|
||||||
* @param callback
|
*
|
||||||
|
* @param callback function to call when a new user is discovered
|
||||||
*/
|
*/
|
||||||
public void sendBroadcast(String message, NetDiscoverer.ResponseReceivedCallback callback) {
|
public static void discoverActiveUsers(ResponseReceivedCallback callback) {
|
||||||
NetDiscoverer.BroadcastSender sender = new NetDiscoverer.BroadcastSender(message, callback);
|
ResponseListener receiver = new ResponseListener(callback);
|
||||||
|
BroadcastSender sender = new BroadcastSender("USER_DISCOVERY_BROADCAST");
|
||||||
|
receiver.start();
|
||||||
|
sender.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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()
|
||||||
|
);
|
||||||
|
listener.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static class BroadcastSender extends Thread {
|
private static class BroadcastSender extends Thread {
|
||||||
String broadcastMessage;
|
String broadcastMessage;
|
||||||
NetDiscoverer.ResponseReceivedCallback callback;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs and starts a thread that sends a broadcast over the network
|
* Constructs and starts a thread that sends a broadcast over the network
|
||||||
|
*
|
||||||
* @param broadcastMessage The message to send
|
* @param broadcastMessage The message to send
|
||||||
* @param callback The function to call once finished
|
|
||||||
*/
|
*/
|
||||||
public BroadcastSender(String broadcastMessage, NetDiscoverer.ResponseReceivedCallback callback) {
|
public BroadcastSender(String broadcastMessage) {
|
||||||
this.broadcastMessage = broadcastMessage;
|
this.broadcastMessage = broadcastMessage;
|
||||||
this.callback = callback;
|
|
||||||
start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
byte[] buf = broadcastMessage.getBytes();
|
byte[] buf = broadcastMessage.getBytes();
|
||||||
try {
|
try {
|
||||||
DatagramSocket broadcastSocket = new DatagramSocket(DISCOVERY_PORT);
|
for (InetAddress broadcastAddr : listAllBroadcastAddresses()) {
|
||||||
broadcastSocket.setBroadcast(true);
|
DatagramSocket broadcastSocket = new DatagramSocket();
|
||||||
broadcastSocket.bind(null);
|
broadcastSocket.setBroadcast(true);
|
||||||
broadcastSocket.send(new DatagramPacket(buf, buf.length));
|
broadcastSocket.send(new DatagramPacket(buf, buf.length, broadcastAddr, DISCOVERY_PORT));
|
||||||
|
// System.out.println("Broadcast sent with address " + broadcastAddr.toString());
|
||||||
|
}
|
||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
ErrorHandler.getInstance().notifyError(e);
|
ErrorHandler.getInstance().notifyError(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class Listener extends Thread {
|
private static class BroadcastListener extends Thread {
|
||||||
final short port;
|
BroadcastReceivedCallback callback;
|
||||||
|
|
||||||
|
public BroadcastListener(BroadcastReceivedCallback callback) {
|
||||||
public Listener(short port) {
|
this.callback = callback;
|
||||||
this.port = port;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
//TODO
|
while (true) { // TODO: add a stop condition
|
||||||
|
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));
|
||||||
|
|
||||||
|
byte[] buffer = new byte[BROADCAST_BUFFER_SIZE];
|
||||||
|
DatagramPacket receivedPacket = new DatagramPacket(buffer, BROADCAST_BUFFER_SIZE);
|
||||||
|
|
||||||
|
listener.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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ResponseSender extends Thread {
|
||||||
|
String message;
|
||||||
|
InetAddress address;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs and starts a thread that sends a broadcast over the network
|
||||||
|
*
|
||||||
|
* @param message The message to send
|
||||||
|
*/
|
||||||
|
public ResponseSender(InetAddress address, String message) {
|
||||||
|
this.address = address;
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
byte[] buf = message.getBytes();
|
||||||
|
try {
|
||||||
|
DatagramSocket responseSocket = new DatagramSocket();
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ResponseListener extends Thread {
|
||||||
|
ResponseReceivedCallback callback;
|
||||||
|
|
||||||
|
public ResponseListener(ResponseReceivedCallback callback) {
|
||||||
|
this.callback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
while (true) { // TODO: add a stop condition
|
||||||
|
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));
|
||||||
|
|
||||||
|
byte[] buffer = new byte[RESPONSE_BUFFER_SIZE];
|
||||||
|
DatagramPacket receivedPacket = new DatagramPacket(buffer, RESPONSE_BUFFER_SIZE);
|
||||||
|
listener.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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static List<InetAddress> listAllBroadcastAddresses() throws SocketException {
|
||||||
|
List<InetAddress> broadcastList = new ArrayList<>();
|
||||||
|
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
|
||||||
|
|
||||||
|
while (interfaces.hasMoreElements()) {
|
||||||
|
NetworkInterface networkInterface = interfaces.nextElement();
|
||||||
|
if (!networkInterface.isLoopback() && networkInterface.isUp()) {
|
||||||
|
networkInterface.getInterfaceAddresses().stream()
|
||||||
|
.map(InterfaceAddress::getBroadcast)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.forEach(broadcastList::add);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return broadcastList;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public interface ResponseReceivedCallback {
|
public interface ResponseReceivedCallback {
|
||||||
void onActiverUserDiscovered(ActiveUser user);
|
void onResponseReceived(InetAddress ipAddr, String data);
|
||||||
}
|
|
||||||
private interface ResponseSentCallback {
|
|
||||||
void onResponseSent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private interface BroadcastReceivedCallback {
|
private interface BroadcastReceivedCallback {
|
||||||
void onBroadcastReceived(InetAddress ipAddr);
|
void onBroadcastReceived(InetAddress ipAddr, String data);
|
||||||
}
|
|
||||||
private interface BroadcastSentCallback {
|
|
||||||
void onBroadcastSent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,6 @@ public class UserList {
|
||||||
|
|
||||||
private ArrayList<ActiveUser> activeUsers;
|
private ArrayList<ActiveUser> activeUsers;
|
||||||
private ArrayList<PeerUser> inactiveUsers;
|
private ArrayList<PeerUser> inactiveUsers;
|
||||||
private final NetDiscoverer netDiscoverer = new NetDiscoverer();
|
|
||||||
private final DatabaseController db = new DatabaseController();
|
private final DatabaseController db = new DatabaseController();
|
||||||
|
|
||||||
// Make this class observable
|
// Make this class observable
|
||||||
|
@ -49,12 +48,10 @@ public class UserList {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public void discoverActiveUsers() {
|
public void discoverActiveUsers() {
|
||||||
netDiscoverer.sendBroadcast("", new NetDiscoverer.ResponseReceivedCallback() {
|
NetDiscoverer.discoverActiveUsers((ipAddr, data) -> {
|
||||||
@Override
|
ActiveUser newUser = new ActiveUser(ipAddr);
|
||||||
public void onActiverUserDiscovered(ActiveUser user) {
|
activeUsers.add(newUser);
|
||||||
activeUsers.add(user);
|
pcs.firePropertyChange("activeUsers", null, newUser);
|
||||||
pcs.firePropertyChange("activeUsers", null, user);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue