Frage zu Multi Client

Added by mkirches 12 months ago

Hi

ich hoffe dass es die Frage noch nicht gibt und sie nicht zu offensichtlich zu beantworten ist, jedenfalls stehe ich wohl auf dem Schlauch.

In meinem Projekt habe ich einen Server, der sein Interface an einen bestimmten Port auf localhost bindet. Das Interface ist mit SimonRemote annotiert, auf der Clientseite
passiert grundsätzlich das gleiche. Hier kommt noch der Lookup dazu, wie es auch im HelloWorld beispiel gezeigt ist.

Für einen einzigen Client funktioniert auch alles, aber wenn ich versuche einen zweiten Client zu starten erhalte ich eine Lookup Exception, die sagt, dass der
nachgeschlagene Name nicht in der Lookup-Tabelle gefunden werden kann. Leider komme ich im Moment nicht an meinen Code dran, kann daher auch die geneue Exception nicht posten, das würde ich
nachliefern. Interessant war, dass im Lookup-Name in der Exception sowohl die Interfacename des Service-Interfaces als auch die Netzwerkaddresse (IP und Port) enthalten waren.

Meine Frage wäre:
Könnt ihr mir vorab schonmal einen Hinweis geben, ob ich eventuell noch etwas beachten muss, wenn ich mehrere Clients nutzen möchte?

Den Code und die Exception kann ich gerne morgen nachliefern

LG
Michael


Replies (6)

RE: Frage zu Multi Client - Added by achristian 12 months ago

Moin,

SIMON ist es egal ob ein Client oder mehrere oder hunderte angebunden werden. Du musst dazu auch nichts spezielles einstellen/einrichten. Das "geht einfach so".

Neben deinem kurzen Code-Beispiel welches den Fehler demonstriert, wäre die (komplette) Exception inkl. Stacktrace sowie die eingesetzte SIMON Version und die Infos bzgl. des Server/Client Betriebssystems und der Java-Version hilfreich.

Gruß
Alex

RE: Frage zu Multi Client - Added by mkirches 12 months ago

Hallo Alex,

erstmal vielen Dank für deine Antwort, ich dachte mir schon dass SIMON das einfach so unterstützt und hätte es auch nicht anders erwartet. Der Fehler muss also bei mir liegen.

Ich habe gerade in meinem Code gesehen, dass ich in meinem Post einen Fehler gemacht habe: nicht die Interfaces sind mit der SimonRemote Annotation versehen, sondern die implementierenden Klassen. Ich gehe aber davon aus, dass das nicht der Fehler ist, schließlich geht ja der Single-Client-Bbetrieb.

Zunächst mal die Fehlermeldung in der Exception, die ich erhalte inklusive StackTrace

de.root1.simon.exceptions.LookupFailedException: remoteobject with name [SimonRemoteInstance[jcmade.SQLiteClient|ip=/127.0.0.1:47000;sessionID=1;remoteObjectHash=1917710412]] not found in lookup table.
    at de.root1.simon.LookupTable.getRemoteObjectContainer(LookupTable.java:310)
    at de.root1.simon.ProcessMessageRunnable.processEquals(ProcessMessageRunnable.java:643)
    at de.root1.simon.ProcessMessageRunnable.run(ProcessMessageRunnable.java:113)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

Nun zur Implementierung.

Der Server implementiert folgendes Interface:

public interface ServerInterface {

    public void login(ClientInterface client, String applicationName);
}

Die dazu gehörige Implementierung sieht wie folgt aus (gekürzt um Interna)

@SimonRemote(value = {ServerInterface.class})
public class Server implements ServerInterface {

    private final String serverInstanceName;

    public Server(String name) {
        this.serverInstanceName = name;

    }

    @Override
    public void login(ClientInterface client, String applicationName) {
        InetAddress address = Simon.getRemoteInetSocketAddress(client).getAddress();
        int port = Simon.getRemoteInetSocketAddress(client).getPort();

        // Some internal stuff which is not related to any SIMON action

        client.connectionEstablished("Connected");
    }

}

Gestartet wird der Server durch folgenden Code:

try {
   int port = 47000;
   String serverInstanceName = "Java SQLite Server";
   String serverBindName = "JSQLiteServer";
   Registry registry = Simon.createRegistry(port);
   registry.start();
   server = new Server(serverInstanceName);

   registry.bind(serverBindName, server);
} catch (IOException | NameBindingException ex) {
    System.out.println(ex.getMessage());
}

Die Client-Seite ist ähnlich einfach aufgebaut.

public interface ClientInterface {
    void connectionEstablished(String connectMessage);
}

Mit zugehöriger Implementierung

@SimonRemote(value = {ClientInterface.class})
public class SQLiteClient implements ClientInterface {
    private ServerInterface server;

    public SQLiteClient() {

    }

    public void initClient() throws UnknownHostException, LookupFailedException, EstablishConnectionFailed {
        // 'lookup' the server object
        de.root1.simon.Lookup nameLookup = Simon.createNameLookup("127.0.0.1", 47000);
        server = (ServerInterface) nameLookup.lookup("JSQLiteServer");

        // use the serverobject as it would exist on your local machine
        server.login(this, "JCMade");
    }

    @Override
    public void connectionEstablished(String connectMessage) {
        System.out.println("Received message from server:\n\t" + connectMessage);
    }
}

In der Main-Methode meiner Client-Anwendung wird eine Instanz von SQLiteClient erzeugt und durch Aufruf von init initialisiert.

Der beschriebene Fehler tritt auf, wenn ich meine Client-Anwendung zum zweiten mal starte.

Zum Schluss noch die Informationen zur Runtime:

OS: Linux (Ubuntu 16.04)
SIMON: 1.3.0
Java: openjdk version "1.8.0_111"

Gruß
Michael

RE: Frage zu Multi Client - Added by mkirches 12 months ago

Noch eine Ergänzung:

Weitere Tests haben gezeigt, dass ich immer mehr Exceptions bekomme, je mehr Client Instanzen ich starte. Beim Start der dritten Instance bekam ich folgende Ausgabe:

de.root1.simon.exceptions.LookupFailedException: remoteobject with name [SimonRemoteInstance[jcmade.SQLiteClient|ip=/127.0.0.1:47000;sessionID=1;remoteObjectHash=1917710412]] not found in lookup table.
    at de.root1.simon.LookupTable.getRemoteObjectContainer(LookupTable.java:310)
    at de.root1.simon.ProcessMessageRunnable.processEquals(ProcessMessageRunnable.java:643)
    at de.root1.simon.ProcessMessageRunnable.run(ProcessMessageRunnable.java:113)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
de.root1.simon.exceptions.LookupFailedException: remoteobject with name [SimonRemoteInstance[jcmade.SQLiteClient|ip=/127.0.0.1:47000;sessionID=1;remoteObjectHash=480220595]] not found in lookup table.
    at de.root1.simon.LookupTable.getRemoteObjectContainer(LookupTable.java:310)
    at de.root1.simon.ProcessMessageRunnable.processEquals(ProcessMessageRunnable.java:643)
    at de.root1.simon.ProcessMessageRunnable.run(ProcessMessageRunnable.java:113)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

Interpretiere ich möglicherweise diesen "Fehler" falsch? Aufruf von

server.login(this, "JCMade");

funktioniert jeweils, das konnte ich beim Debuggen sehen.

RE: Frage zu Multi Client - Added by achristian 12 months ago

Der zuletzt gezeigte Stack zeigt, dass ein "equals()" auf dem Remote-Objekt nicht mehr funktioniert.

Was machst du mit dem Remote-Objekt am Server welches dir vom Client übergeben wird (--> ClientInterface)? Du kannst damit nur arbeiten wenn der Client noch verbunden ist. Ist der Client weg, kannst du's nicht mehr benutzen. Und da gehören nicht nur die Remote-Methoden laut Interface, sondern auch toString(), equals() und hashCode() dazu.

Ich vermute mal du hast dir das Client-Interface am Server in ne Hashmap oder sowas gespeichert?

Schau dir mal das hier an:

http://dev.root1.de/projects/simon/wiki/Sample_session_pattern

Speziell was das Interface "SimonUnreferenced" angeht.

Damit bekommst du mit wenn der Client wegfällt und kannst aufräumen...

RE: Frage zu Multi Client - Added by mkirches 12 months ago

Mit den Client-Instanzen passiert auf der Server-Seite noch garnichts sinnvolles, bisher wird der tatsächlich nur genutzt, um Routinen aufzurufen. Meine Idee war es aber, die Remote-Objekte auf der Serverseite in eine HashMap zu speichern um prüfen zu können ob Clients noch am Leben sind.

Das Beispiel zum Thema Sessions werde ich mir mal genau anschauen, ich glaube das wird noch einige meiner Fragen beantworten.

Vielen Dank für die schnelle Hilfe

RE: Frage zu Multi Client - Added by achristian 12 months ago

Das Session Konzept wird dir das Leben da einfacher machen. Und behalte im Hinterkopf, dass equals(), hashcode() und toString() auch Remote-Methoden sind, welche unter anderen von HashMap und Co. intern benutzt werden.
Das hat bei dir zu exakt dem Fehler geführt: Der Server hat versucht den equals() aufruf auf einem solchen Client-Objekt zum Client zu schicken und hat da nichts mehr passendes gefunden, weil der zugehörige Client schon weg war.

(1-6/6)