In einem anderem Thread: http://www.java-forum.org/thema/architekturfrage.174012/#post-1097691 habe ich mich mal über andere Wege der Client/Server Kommunikation als RMI erkundigt.
Für meine Zwecke (man kann sich eine (simple und private) SmartHome Steuerung vorstellen, was den Funktionsumfang angeht) scheint mir die Nutzung von Websockets die richtige Lösung.
Mittlerweile habe ich mich schon ein wenig eingearbeitet (bin ja nur begeisterter Hobby Programmierer) und es geschafft einen lauffähigen Server und Client zu erstellen wobei der Client auch in der Lage ist Nachrichten (Strings) an den Server zu schicken.
Das Konzept dahinter habe ich aber immer noch nicht ganz verstanden - ich hänge da wohl noch den Interfaces von RMI nach...
Ich habe nun folgendes PROBLEM: Will ich nun beim Erhalt einer Nachricht Hardware am Server ansteuern kracht mir der Client zusammen weil ich die Klasse für die Hardware im WebSocketAdapter importiere und clientseitig ist natürlich keine Hardware da... => Chrash!
Exportiere ich den Code auf den Server (*.jar) und lösche dann aus dem Client die Referenzen auf die Hardware und lasse den Client in der IDE laufen erhält der Server die Nachricht und führt auf der HW die Aktionen aus. Der Client rennt natürlich weiter weil er ja keine Ahnung mehr von der HW hat...
Wie kann ich nun die HW am Server steuern?
Ich dachte ich schicke einen "Steuerbefehl" (JSON oder sowas) zum Server und der verarbeitet es dann - nur wie?
Oder kann ich hier doch irgendwas ganz anderes machen?
Nachstehend mal meine simple gehaltene Code Basis (die ich aus einem Beispiel habe - siehe Kommentar) + plus Anmerkungen von mir wo ich da was mache..
Ich danke schon im Voraus für alle Ratschläge und bitte gleichzeitig um Hilfe
Server:
Client:
WebsocketServlet: EventServlet
Websocketadapter: EventSocket
Für meine Zwecke (man kann sich eine (simple und private) SmartHome Steuerung vorstellen, was den Funktionsumfang angeht) scheint mir die Nutzung von Websockets die richtige Lösung.
Mittlerweile habe ich mich schon ein wenig eingearbeitet (bin ja nur begeisterter Hobby Programmierer) und es geschafft einen lauffähigen Server und Client zu erstellen wobei der Client auch in der Lage ist Nachrichten (Strings) an den Server zu schicken.
Das Konzept dahinter habe ich aber immer noch nicht ganz verstanden - ich hänge da wohl noch den Interfaces von RMI nach...
Ich habe nun folgendes PROBLEM: Will ich nun beim Erhalt einer Nachricht Hardware am Server ansteuern kracht mir der Client zusammen weil ich die Klasse für die Hardware im WebSocketAdapter importiere und clientseitig ist natürlich keine Hardware da... => Chrash!
Exportiere ich den Code auf den Server (*.jar) und lösche dann aus dem Client die Referenzen auf die Hardware und lasse den Client in der IDE laufen erhält der Server die Nachricht und führt auf der HW die Aktionen aus. Der Client rennt natürlich weiter weil er ja keine Ahnung mehr von der HW hat...
Wie kann ich nun die HW am Server steuern?
Ich dachte ich schicke einen "Steuerbefehl" (JSON oder sowas) zum Server und der verarbeitet es dann - nur wie?
Oder kann ich hier doch irgendwas ganz anderes machen?
Nachstehend mal meine simple gehaltene Code Basis (die ich aus einem Beispiel habe - siehe Kommentar) + plus Anmerkungen von mir wo ich da was mache..
Ich danke schon im Voraus für alle Ratschläge und bitte gleichzeitig um Hilfe
Server:
Java:
package jettyDemo;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
public class EventServer
/**
* https://github.com/jetty-project/embedded-jetty-websocket-examples/tree/master/native-jetty-websocket-example/src/main/java/org/eclipse/jetty/demo
*/
{
public static void main(String[] args)
{
Server server = new Server();
ServerConnector connector = new ServerConnector(server);
connector.setPort(8080);
server.addConnector(connector);
// Setup the basic application "context" for this application at "/"
// This is also known as the handler tree (in jetty speak)
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
server.setHandler(context);
// Add a websocket to a specific path spec
ServletHolder holderEvents = new ServletHolder("ws-events", EventServlet.class);
context.addServlet(holderEvents, "/events/*");
try
{
server.start();
server.dump(System.err);
server.join();
}
catch (Throwable t)
{
t.printStackTrace(System.err);
}
}
}
Client:
Java:
package jettyDemo;
import java.net.URI;
import java.util.concurrent.Future;
import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.client.WebSocketClient;
public class EventClient
/**
* https://github.com/jetty-project/embedded-jetty-websocket-examples/tree/master/native-jetty-websocket-example/src/main/java/org/eclipse/jetty/demo
*/
{
public static void main(String[] args)
{
System.out.println("client gestartet...");
URI uri = URI.create("ws://localhost:8080/events/");
WebSocketClient client = new WebSocketClient();
try
{
try
{
client.start();
// The socket that receives events
EventSocket socket = new EventSocket();
// Attempt Connect
Future<Session> fut = client.connect(socket,uri);
// Wait for Connect
Session session = fut.get();
// Send a message
System.out.println("Client sends a message...");
session.getRemote().sendString("Hello");
//hier habe ich mal getestet wie schnell das Zeug reagiert - geht eh flott :D
for (int i = 0; i < 100; i++) {
System.out.println(i);
session.getRemote().sendString("Hello");
}
Close session
session.close(1000, "Clientside stop");
// session.close();
}
finally
{
client.stop();
}
}
catch (Throwable t)
{
t.printStackTrace(System.err);
}
}
}
WebsocketServlet: EventServlet
Java:
package jettyDemo;
import org.eclipse.jetty.websocket.servlet.WebSocketServlet;
import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory;
@SuppressWarnings("serial")
public class EventServlet extends WebSocketServlet
/**
* https://github.com/jetty-project/embedded-jetty-websocket-examples/tree/master/native-jetty-websocket-example/src/main/java/org/eclipse/jetty/demo
*
* Abstract Servlet used to bridge the Servlet API to the WebSocket API.
* To use this servlet, you will be required to register your websockets with the WebSocketServletFactory
* so that it can create your websockets under the appropriate conditions.
*/
{
@Override
public void configure(WebSocketServletFactory factory)
{
factory.register(EventSocket.class);
}
}
Java:
package jettyDemo;
import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.WebSocketAdapter;
public class EventSocket extends WebSocketAdapter
/**
* https://github.com/jetty-project/embedded-jetty-websocket-examples/tree/master/native-jetty-websocket-example/src/main/java/org/eclipse/jetty/demo
*
* provides the functionality of the socket connection.
*/
//hier generiere ich mir meine Hardwareklasse:
HardwareKlasse hardware = new HardwarKlasse();
{
@Override
public void onWebSocketConnect(Session sess)
{
super.onWebSocketConnect(sess);
System.out.println("Socket Connected: " + sess);
}
@Override
public void onWebSocketText(String message)
{
super.onWebSocketText(message);
System.out.println("Received TEXT message: " + message);
//hier mal mein (Pseuo)Code wenn hardware angesprochen werden soll:
if (message.equals("BefehlIrgendwasZuTun")
{
hardware.doSomething
}
//natürlich läuft der Code so nicht, da die Hardware ja nur am Server liegt. Nehme ich die zwei Codeteile von mir raus und starte den Client neu (in der IDE) und lasse am Server den Code MIT der Hardware gehts wie gewollt. Nur will ich das nicht... ist ja komplett unelegang gelöst...
}
@Override
public void onWebSocketClose(int statusCode, String reason)
{
super.onWebSocketClose(statusCode,reason);
System.out.println("Socket Closed: [" + statusCode + "] " + reason);
}
@Override
public void onWebSocketError(Throwable cause)
{
super.onWebSocketError(cause);
cause.printStackTrace(System.err);
}
}