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;
|
||||
|
||||
import fr.insa.clavardator.users.ActiveUser;
|
||||
import fr.insa.clavardator.util.ErrorHandler;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.DatagramSocket;
|
||||
import java.net.InetAddress;
|
||||
import java.net.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class NetDiscoverer {
|
||||
private static final short DISCOVERY_PORT = 31596;
|
||||
private static final short RESPONSE_PORT = 31597;
|
||||
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;
|
||||
|
||||
public NetDiscoverer() {}
|
||||
private NetDiscoverer() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param message
|
||||
* @param callback
|
||||
* 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
|
||||
*/
|
||||
public void sendBroadcast(String message, NetDiscoverer.ResponseReceivedCallback callback) {
|
||||
NetDiscoverer.BroadcastSender sender = new NetDiscoverer.BroadcastSender(message, callback);
|
||||
public static void discoverActiveUsers(ResponseReceivedCallback 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 {
|
||||
String broadcastMessage;
|
||||
NetDiscoverer.ResponseReceivedCallback callback;
|
||||
|
||||
/**
|
||||
* Constructs and starts a thread that sends a broadcast over the network
|
||||
*
|
||||
* @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.callback = callback;
|
||||
start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
byte[] buf = broadcastMessage.getBytes();
|
||||
try {
|
||||
DatagramSocket broadcastSocket = new DatagramSocket(DISCOVERY_PORT);
|
||||
broadcastSocket.setBroadcast(true);
|
||||
broadcastSocket.bind(null);
|
||||
broadcastSocket.send(new DatagramPacket(buf, buf.length));
|
||||
for (InetAddress broadcastAddr : listAllBroadcastAddresses()) {
|
||||
DatagramSocket broadcastSocket = new DatagramSocket();
|
||||
broadcastSocket.setBroadcast(true);
|
||||
broadcastSocket.send(new DatagramPacket(buf, buf.length, broadcastAddr, DISCOVERY_PORT));
|
||||
// System.out.println("Broadcast sent with address " + broadcastAddr.toString());
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
ErrorHandler.getInstance().notifyError(e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static class Listener extends Thread {
|
||||
final short port;
|
||||
private static class BroadcastListener extends Thread {
|
||||
BroadcastReceivedCallback callback;
|
||||
|
||||
|
||||
public Listener(short port) {
|
||||
this.port = port;
|
||||
public BroadcastListener(BroadcastReceivedCallback callback) {
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
@Override
|
||||
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 {
|
||||
void onActiverUserDiscovered(ActiveUser user);
|
||||
}
|
||||
private interface ResponseSentCallback {
|
||||
void onResponseSent();
|
||||
void onResponseReceived(InetAddress ipAddr, String data);
|
||||
}
|
||||
|
||||
private interface BroadcastReceivedCallback {
|
||||
void onBroadcastReceived(InetAddress ipAddr);
|
||||
}
|
||||
private interface BroadcastSentCallback {
|
||||
void onBroadcastSent();
|
||||
void onBroadcastReceived(InetAddress ipAddr, String data);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -12,7 +12,6 @@ public class UserList {
|
|||
|
||||
private ArrayList<ActiveUser> activeUsers;
|
||||
private ArrayList<PeerUser> inactiveUsers;
|
||||
private final NetDiscoverer netDiscoverer = new NetDiscoverer();
|
||||
private final DatabaseController db = new DatabaseController();
|
||||
|
||||
// Make this class observable
|
||||
|
@ -49,12 +48,10 @@ public class UserList {
|
|||
*
|
||||
*/
|
||||
public void discoverActiveUsers() {
|
||||
netDiscoverer.sendBroadcast("", new NetDiscoverer.ResponseReceivedCallback() {
|
||||
@Override
|
||||
public void onActiverUserDiscovered(ActiveUser user) {
|
||||
activeUsers.add(user);
|
||||
pcs.firePropertyChange("activeUsers", null, user);
|
||||
}
|
||||
NetDiscoverer.discoverActiveUsers((ipAddr, data) -> {
|
||||
ActiveUser newUser = new ActiveUser(ipAddr);
|
||||
activeUsers.add(newUser);
|
||||
pcs.firePropertyChange("activeUsers", null, newUser);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue