Hallo!
Ich möchte eine verteilte Anwendung schreiben, bei der insbesondere eine Komponente namens Controller und eine namens Worker auf verschiedenen Rechnern laufen sollen. Üblicherweise sendet der Controller and den Worker Befehle, die dann von diesem ausgeführt werden. Manchmal jedoch möchte auch der Worker eine Information unaufgefordert an den Controller senden.
Mein Plan war bisher, Java RMI hierfür zu nutzen. Dazu wollte ich auf einem Rechner den Controller laufen lassen, auf einem weiteren den Worker, und auf einem der beiden oder einem dritten eine RMI Registry. Idee war, dass nun Controller und Worker sich bei der Registry anmelden und dann jeweils wechselseitig ein Remote-Objekt des anderen holen, um diesem dann Nachricht zuzusenden.
Problem: Es scheint nicht möglich zu sein, ein Remote-Objekt bei der Registry anzumelden, wenn dieses nicht auf demselben Rechner wie die Registry implementiert ist (zumindest gelingt mir das nicht).
Frage 1: Stimmt das? Oder kann man das Problem irgendwie umgehen?
Alternative: Nun gäbe es natürlich die Möglichkeit, auf dem Controller- und dem Worker-Rechner jeweils zusätzlich eine eigene RMI Registry zu starten, so dass die beiden Komponenten die Implementierung des jeweils anderen bei seiner Registry erfragen können. Das finde ich aber doof, da dann auch wechselseitig die IPs bekannt gemacht werden müssen. Stattdessen wäre vielleicht folgendes möglich (?):
Der Controller (RMI-Client) registriert sich anfangs als Listener-beim Worker (RMI-Server), indem er diesem eine Art Posteingangs-Objekt (den Listener) übersendet. Fortan kann nun auch der Worker jederzeit Listener-Funktionen des Controllers aufrufen. Mit dieser Alternative versuche ich also, eine bidirektionale Kommunikation herzustellen, obwohl nur eine einzige RMI Registry genutzt wird.
Frage 2: Ist das so möglich? Ich erahne dort folgendes Problem (welches vielleicht aber gar nicht existiert). Wenn der Controller das Listener-Objekt an der Worker gesendet hat und aus diesem Remote-Call zurückgekehrt ist, wird das Listener-Objekt dann vielleicht nach einiger Zeit ungültig? Oder darf es problemlos im Worker gespeichert werden und jederzeit später auch für Rückaufrufe zum Controller verwendet werden?
Zur Verdeutlichung hier eine Rohstruktur dieser bidirektionalen Kommunikation:
[Java]
// RMI-Server
class Worker {
public doSomething() {
// Aufgerufen vom RMI-Client, implementiert auf Seiten des Workers (RMI-Server)
}
public registerListener(Listener listener) {
// aufgerufen vom RMI-Client via Remote.
// übergibt insbesondere einen Listener, der auf der RMI-Client-Seite implementiert ist,
// und ab und an von hier aus (also vom RMI-Server aus) aufgerufen wird.
}
}
[/Java]
[Java]
// RMI-Client
class Controller {
Listener listener;
(...)
}
[/Java]
[Java]
// Hilfsklasse, implementiert auf RMI-Client-Seite
class Listener {
public somethingHappened(String s) {
// Aufgerufen vom RMI-Server, implementiert auf Seiten des Controllers (RMI-Client)
}
}
[/Java]
Also: Weiß jemand, ob es hierbei ein Problem gibt? Oder gibt es vielleicht noch eine elegantere Lösung?
Würde mich sehr über Hilfe freuen!
Danke,
kopfsalat
Ich möchte eine verteilte Anwendung schreiben, bei der insbesondere eine Komponente namens Controller und eine namens Worker auf verschiedenen Rechnern laufen sollen. Üblicherweise sendet der Controller and den Worker Befehle, die dann von diesem ausgeführt werden. Manchmal jedoch möchte auch der Worker eine Information unaufgefordert an den Controller senden.
Mein Plan war bisher, Java RMI hierfür zu nutzen. Dazu wollte ich auf einem Rechner den Controller laufen lassen, auf einem weiteren den Worker, und auf einem der beiden oder einem dritten eine RMI Registry. Idee war, dass nun Controller und Worker sich bei der Registry anmelden und dann jeweils wechselseitig ein Remote-Objekt des anderen holen, um diesem dann Nachricht zuzusenden.
Problem: Es scheint nicht möglich zu sein, ein Remote-Objekt bei der Registry anzumelden, wenn dieses nicht auf demselben Rechner wie die Registry implementiert ist (zumindest gelingt mir das nicht).
Frage 1: Stimmt das? Oder kann man das Problem irgendwie umgehen?
Alternative: Nun gäbe es natürlich die Möglichkeit, auf dem Controller- und dem Worker-Rechner jeweils zusätzlich eine eigene RMI Registry zu starten, so dass die beiden Komponenten die Implementierung des jeweils anderen bei seiner Registry erfragen können. Das finde ich aber doof, da dann auch wechselseitig die IPs bekannt gemacht werden müssen. Stattdessen wäre vielleicht folgendes möglich (?):
Der Controller (RMI-Client) registriert sich anfangs als Listener-beim Worker (RMI-Server), indem er diesem eine Art Posteingangs-Objekt (den Listener) übersendet. Fortan kann nun auch der Worker jederzeit Listener-Funktionen des Controllers aufrufen. Mit dieser Alternative versuche ich also, eine bidirektionale Kommunikation herzustellen, obwohl nur eine einzige RMI Registry genutzt wird.
Frage 2: Ist das so möglich? Ich erahne dort folgendes Problem (welches vielleicht aber gar nicht existiert). Wenn der Controller das Listener-Objekt an der Worker gesendet hat und aus diesem Remote-Call zurückgekehrt ist, wird das Listener-Objekt dann vielleicht nach einiger Zeit ungültig? Oder darf es problemlos im Worker gespeichert werden und jederzeit später auch für Rückaufrufe zum Controller verwendet werden?
Zur Verdeutlichung hier eine Rohstruktur dieser bidirektionalen Kommunikation:
[Java]
// RMI-Server
class Worker {
public doSomething() {
// Aufgerufen vom RMI-Client, implementiert auf Seiten des Workers (RMI-Server)
}
public registerListener(Listener listener) {
// aufgerufen vom RMI-Client via Remote.
// übergibt insbesondere einen Listener, der auf der RMI-Client-Seite implementiert ist,
// und ab und an von hier aus (also vom RMI-Server aus) aufgerufen wird.
}
}
[/Java]
[Java]
// RMI-Client
class Controller {
Listener listener;
(...)
}
[/Java]
[Java]
// Hilfsklasse, implementiert auf RMI-Client-Seite
class Listener {
public somethingHappened(String s) {
// Aufgerufen vom RMI-Server, implementiert auf Seiten des Controllers (RMI-Client)
}
}
[/Java]
Also: Weiß jemand, ob es hierbei ein Problem gibt? Oder gibt es vielleicht noch eine elegantere Lösung?
Würde mich sehr über Hilfe freuen!
Danke,
kopfsalat