Wie kann ich bei meinem RMI-Server Änderungen der Netzwerk-Umgebung autom. erkennen

mcdroemmel

Mitglied
Hallo zusammen,

habe eine Java-App-Server-Anwendung mit meiner Business-Logik. Da diese Anwendung erzeugte Daten auf Rechner der Benutzer verteilen muss, haben alle Benutzer auf ihrem Rechner eine Java-Anwendung installiert die einen RMI-Server bereitstellt.
Diese Anwendung erkennt beim Start automatisch die Netzwerke (es können mehrere aktive Netzwerk-Karten wie eben Ethernet und WiFi aktiv sein), startet auf einem festgelegten Port jeder erkannten Netzwerk-Karte/Ip-Adresse die Java-Registry und bindet mein Remote-Objekt an die Registry.
Die Anwendung macht dann noch ein Sys-Tray-Icon mit Menü auf, mit dem bei einem Wechsel der Netzwerk-Konfiguration (Benutzer klinkt sein Notebook aus Doking-Station und aktiviert mit WiFi um mobil online zu bleiben) manuell die Netzwerk-Konfiguration neu eingelesen und die Registry/Remote-Objekte an die neuen Adressen gebunden werden können.

Funktioniert alles fein. Es setzt aber vorraus, das der Nutzer eben weiß das er z.B. sein Notebook ausdockt, sein VPN aktiviert, Wifi aktiviert etc und damit irgendeine Änderung der Netzwerk-Konfiguration auslöst und eben erkennt, dass die Anwendung manuell refresht werden muss.

Ich würde jetzt die Anwendung gern selbst erkennen lassen ob die Netzwerk-Konfiguration sich geändert hat. Vielleicht über irgendeine Call-Back-Methode oder so.
Hat jemand eine Idee wie sich das realisieren lässt ?

Vielen Dank im Vorraus
McD
 
Also wenn du nur benachrichtigt werden möchtest wenn Netzwerkinterfaces hinzugefügt/entfernt werden würde ich dir Empfehlen, jede Sekunde 1x mit einem Thread dafür zu überprüfen ob sich die Liste der verfügbaren Netzwerkinterfaces geändert hat. Der Aufwand dürfte denke ich vertretbar sein. Wie das geht weißt du denke ich nach dem was ich in dem Post gelesen habe. Wenn nicht melde dich nochmal.

MfG Technoblade
 
Hallo,

schau mal hier:
Java:
package de.tutorials;

import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.concurrent.Executors;

import static java.util.concurrent.TimeUnit.SECONDS;

public class NetworkChangeDetectorExample {

  public static void main(String[] args) {
    Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(new NetworkChangeDetector(), 1, 5, SECONDS);
  }

  static class NetworkChangeDetector implements Runnable {

    private volatile Map<String, InterfaceEntry> knownInterfaces;


    public void run() {
      try {
        detectNetworkChange();
      } catch (Exception ex) {
        ex.printStackTrace();
      }
    }


    private void detectNetworkChange() {
      Map<String, InterfaceEntry> detectedNetworkInterfaces = detectAvailableNetworkInterfaces();

      if (knownInterfaces == null) {
        knownInterfaces = detectedNetworkInterfaces;
        //TODO notify listeners about initial discovered interfaces
      } else {
    	NetworkChanges networkChanges = computeNetworkChanges(knownInterfaces, detectedNetworkInterfaces);
        if (!networkChanges.isEmpty()) {
          generateNetworkChangedEvents(networkChanges, detectedNetworkInterfaces);
          knownInterfaces.clear();
          knownInterfaces = detectedNetworkInterfaces;
        }
      }
    }


    protected void generateNetworkChangedEvents(NetworkChanges networkStatus, Map<String, InterfaceEntry> detectedNetworkInterfaces) {
    	//TODO notify listeners about network changes
    }


    protected Map<String, InterfaceEntry> detectAvailableNetworkInterfaces() {
      Map<String, InterfaceEntry> detectedInterfaces = new TreeMap<String, InterfaceEntry>();
      try {
        for (NetworkInterface iface : Collections.list(NetworkInterface.getNetworkInterfaces())) {
          detectedInterfaces.put(iface.getName(), new InterfaceEntry(iface));
        }
      } catch (SocketException e) {
        e.printStackTrace();
      }
      return detectedInterfaces;
    }


    public NetworkChanges computeNetworkChanges(Map<String, InterfaceEntry> knownInterfaces, Map<String, InterfaceEntry> detectedNetworkInterfaces) {
      NetworkChanges networkStatus = new NetworkChanges();

      Set<String> newNetworkInterfaceNames = new TreeSet<String>(detectedNetworkInterfaces.keySet());
      newNetworkInterfaceNames.removeAll(knownInterfaces.keySet());

      Set<String> removedNetworkInterfaceNames = new TreeSet<String>(knownInterfaces.keySet());
      removedNetworkInterfaceNames.removeAll(detectedNetworkInterfaces.keySet());
      removedNetworkInterfaceNames.removeAll(newNetworkInterfaceNames);

      Set<String> potentiallyChangedInterfaceNames = new TreeSet<String>(knownInterfaces.keySet());
      potentiallyChangedInterfaceNames.addAll(detectedNetworkInterfaces.keySet());
      potentiallyChangedInterfaceNames.removeAll(newNetworkInterfaceNames);
      potentiallyChangedInterfaceNames.removeAll(removedNetworkInterfaceNames);

      if (!removedNetworkInterfaceNames.isEmpty()) {
        System.out.println("Removed network interfaces: " + removedNetworkInterfaceNames);
        networkStatus.getRemovedNetworkInterfaces().addAll(removedNetworkInterfaceNames);
      }

      if (!newNetworkInterfaceNames.isEmpty()) {
        System.out.println("new network interfaces: " + newNetworkInterfaceNames);
        networkStatus.getNewNetworkInterfaces().addAll(newNetworkInterfaceNames);
      }

      for (String ifaceName : potentiallyChangedInterfaceNames) {
        InterfaceEntry oldInterfaceEntry = knownInterfaces.get(ifaceName);
        InterfaceEntry newInterfaceEntry = detectedNetworkInterfaces.get(ifaceName);

        if (networkInterfaceChanged(oldInterfaceEntry, newInterfaceEntry)) {
          Pair<InterfaceEntry, InterfaceEntry> oldNewEntry = new Pair<InterfaceEntry, InterfaceEntry>(oldInterfaceEntry, newInterfaceEntry);
          networkStatus.getChangedNetworkInterfaces().put(ifaceName, oldNewEntry);
          System.out.println("Network interface changed: Old: " + oldInterfaceEntry + " New: " + newInterfaceEntry);
        }
      }

      return networkStatus;
    }


    public boolean networkInterfaceChanged(InterfaceEntry oldInterface, InterfaceEntry newInterface) {
      InetAddress oldAddress = oldInterface.getPrimaryAddress();
      InetAddress newAddress = newInterface.getPrimaryAddress();

      if(oldAddress == newAddress){
        return false;
      }

      if((oldAddress != null && newAddress == null)|| (newAddress != null && oldAddress == null)){
        return true;
      }

      return !oldAddress.equals(newAddress);
    }
  }

  static class NetworkChanges {
    private final Set<String> newNetworkInterfaces = new TreeSet<String>();
    private final Set<String> removedNetworkInterfaces = new TreeSet<String>();

    private final Map<String, Pair<InterfaceEntry, InterfaceEntry>> changedNetworkInterfaces = new TreeMap<String, NetworkChangeDetectorExample.Pair<InterfaceEntry, InterfaceEntry>>();


    public boolean isEmpty() {
      return newNetworkInterfaces.isEmpty() && newNetworkInterfaces.isEmpty() && changedNetworkInterfaces.isEmpty();
    }


    public Map<String, Pair<InterfaceEntry, InterfaceEntry>> getChangedNetworkInterfaces() {
      return changedNetworkInterfaces;
    }


    public Set<String> getNewNetworkInterfaces() {
      return newNetworkInterfaces;
    }


    public Set<String> getRemovedNetworkInterfaces() {
      return removedNetworkInterfaces;
    }
  }

  static class InterfaceEntry {
    final String name;
    final InetAddress primaryAddress;
    final NetworkInterface networkInterface;


    public InterfaceEntry(NetworkInterface networkInterface) {
      this.name = networkInterface.getName();
      this.primaryAddress = getPrimaryIPV4Address(networkInterface); //TODO add support for IPV6
      this.networkInterface = networkInterface;
    }


    protected InetAddress getPrimaryIPV4Address(NetworkInterface networkInterface) {
      List<InetAddress> inetAddresses = Collections.list(networkInterface.getInetAddresses());

      Inet4Address inet4address = null;
      for (InetAddress adr : inetAddresses) {
        if (adr instanceof Inet4Address) {
          inet4address = (Inet4Address) adr;
          break;
        }
      }

      return inet4address;
    }


    public String getName() {
      return name;
    }


    public InetAddress getPrimaryAddress() {
      return primaryAddress;
    }


    public NetworkInterface getNetworkInterface() {
      return networkInterface;
    }


    @Override
    public String toString() {
      return "NetInterfaceEntry [name=" + name + ", primaryAddress=" + primaryAddress + "]";
    }

  }

  static class Pair<K, V> {
    private final K key;
    private final V value;


    public Pair(K key, V value) {
      this.key = key;
      this.value = value;
    }


    public K getKey() {
      return key;
    }


    public V getValue() {
      return value;
    }
  }

}

Gruß Tom
 
Zurück