Wie gibt man dem Server Befehle?

Hallo

Nehmen wir an ich habe einen Server und einen Client. Der Server besitzt die Klasse EmailSender.

Ich möchte mich zum Server Verbinden und per Knopfdruck folgendes Erreichen… Der Server soll ein Objekt von EmailSender erzeugen und dann die MEthode sendeEmail aufrufen.

Wie kann ich das realisieren ohne das der Client all die benötigten Klassen des Servers besitzt???

Ich habe bis jetzt es auf 2 Arten geschaft.

  1. Ich habe dem Server immer nur Strings gesendet, die der Server ausgeweret hat. Je nachdem wurde dann die richtige Methode auf der Server Seite ausgeführt. Ich finde diese Lösung aber iregndwie bescheuert.

  2. Ich habe es mit dem Kommando Muster probiert, durch sendeEmailKommando.execute(). Tat der Server dann was er soll. Bei dieser Methode musste der Client aber die Klasse EmailSender besitzen weil die erzeugung im Kommondo auf der Client Seite stand. Diese Methode finde ich noch schlechter. Warum sollte der Client den ganzen COde des Servers besitzen.

Wie macht man das den nun richtig?

Wie hast du die Client-Server-Kommunikation bisher umgesetzt? Ganz plain mit Sockets? Dann bleibt dir nicht viel mehr als die Variante 1.

Die “richtige” Antwort gibts hier nicht, du hast aber viele Alternativen. Von REST über SOAP bis hin zu RMI.
Falls du nur ein wenig rumspielen willst, würde deine Variante 1 nehmen, sowas ist schnell und einfach implementiert.

  1. ist schon der richtige Ansatz.

Allerdings verwendet man dafür meist die entsprechenden Technologien, damit das rund läuft.

Ein klassischer Webservice macht nichts anderes.

Ein Servlet Container z.B. Jetty, auf dem ein HttpServlet läuft. Und in dem Servlet kann man dann beliebigen Code ausführen und die ansteuerung läuft über beliebige Web-Technologien oder auch einen Browser.

  1. ist auch eine Möglichkeit, also über RMI. Macht Sinn, wenn das ganze etwas komplexer ist als nur einen einzigen Befehl auszuführen.
    Auf der Clientseite benötigt man meist auch einiges an Code, dass man hier in Form von Interface bereitgestellt bekommen kann, gegen dass man programmiert.

die zweite Variante funktioniert gewiss nicht, oder extrem gebaut, man kann nicht so leicht ausführbaren Code zum Server übertragen,
vielleicht steht der Code wiederum in Klassen, die schon auf beiden Seiten bekannt sind…


du musst dir überlegen, was du haben willst, vergiss erstmal Server/ Client, sondern arbeite mit zwei normalen Klassen in einem Java-Projekt,
was genau soll von Kasse A auf zu Klasse B hin passieren damit B EmailSender erzeugt und dort eine Methode aufruft?

dass A EmailSender kennen muss ist doch ziemlich abwegig, A könnte stattdessen einfach eine Methode B.bearbeiteEmail() aufrufen,
mehr ist doch im einfachen Falle nicht zu beachten

B.bearbeiteEmail() ist objektorientierter schöner, sonst quasi gleichwertig zu einem allgemeineren String-Kommando B.bearbeite(“Email”)

wertvoller bei Methodenaufrufen ist noch die Übergabe von Objekten als Parameter,
nennt sich dann RPC, RMI, SIMON,
bekannt sein muss auf beiden Seiten ein Interface für die aufzurufende Klasse beim Server, mit Methode/n, sowie alle Klassen die als Parameter übertragen werden

Was soll denn an String-basierter Kommunikation so schlimm sein ?
Wenn man mal Kompression und Verschlüsselung weglässt arbeiten viele Standard-Protokolle auf dieser ebene, allen voran HTTP, SMTP und FTP.
Bei diesen Protokollen ist halt festgelegt welche Keywords in welcher Syntax zulässig sind und was Payload-Daten sind. Der Rest wird entweder ignoriert oder mit einem Fehler beantwortet. Das ist ja auch der Sinn hinter einem Protokoll. Ob dies nun “binär” auf Bit-/Byte-Ebene arbeitet oder man halt menschen-lesbare Strings nutzt ist dabei eigentlich egal.

Um so erstaunlicher ist es das man sich “damals” als viele der heutigen “Standard”-Protkolle entwickelt wurden eben dafür entschieden hat, obwohl die Übertragungsgeschwindigkeit nach heutigem Maß gegen 0 ging, Verbindungen und Speicherplatz teuer waren und die Verarbeitungsgeschwindigkeit uns heute wie Stillstand vorkommen mag.

Und für die ersten Geh-Versuche wie z.B. ein Chat mit Kommandos oder einen “Anwendungs-Server” ist es dank der einfachen Umsetzung auch ideal zum lernen bevor man sich dem Wahnsinn gibt und versucht alles auf Bit-Ebene zu komprimieren (auch wenn man auf Bit-/Byte-Ebene effizienter arbeiten kann).

auch wenn etwas Offtopic: Übertragungsgeschwindigkeit betrifft doch hauptsächlich Bilder, große Dateien,
die einzelnen Pakete sind immer gleich schnell, Anteil wichtiger Kommandos am Anfang ist da doch überschaubar, wenige Prozent selbst innerhalb nur eines 8 KB-Pakets?

freilich könnte man allgemein optimieren, auch jedes HTML-Document mit all seinen Tags in binär :wink:
allein die aktuelle Seite dieses Thread hier im Forum sind 100kb in .htm (im IE, sogar 137kb mit mehr JavaScript in Firefox)
dazu die weiteren Dateien, ckeditor.js 367 KB, main-rollup.css 95KB usw., hoffentlich gecacht… wie vielleicht die Avatare

weil man so etwas immer in eine eigene JAR auslagert und in den Classpath dem Server und Client hinzufügt

@mogel
etwas kruder Satz, aber falls du damit andeutest, dass es ok ist das der Client den Code des Servers könnt, möchte ich da widersprechen

drei verschiedene Projekte, Client, Common, Server, das klingt doch nach gängiger Praxis, oder genauer zu diskutieren?
im Kleinen kann man natürlich alles zusammenlegen, lohnt sich kaum,

richtig schlimm wäre es auch nicht wenn alle alles kennen, was sollte der Client schon schlimmes mit Server-Code anfangen,
lokal entsprechende Objekte selber zu erzeugen statt den wirklichen Server anzusprechen sollte als Fehler auffallen (etwa nicht verbundene DB…),
falls nicht alles ganz egal aufgebaut ist

das ist nicht viel anders als die normale Sichtbarkeit unter Java-Klassen, public vs package-protected usw.,
einfaches Aufräumen, was nicht gebraucht ist stört nur in Auswahllisten

(edit: ok, nach langen Posting nochmal gelesen sprichst du wohl vom Common-Porjekt/ Jar :wink: )

ja okay, habe mir irgendwas eingefangen und schnell nach Hause.

Ich wollte aber exakt auf Server, Client, Common hinaus. Und in Common nur das was beide brauchen.

Danke für den Hinweise das es mit String scheinbar normal ist.

Dennoch bin ich jetzt auf RMI gestossen und hoffe auf eure Unterstüzung im nächsten Thread.