// Runs a story of FILIUS' echo server (ServerBaustein) and generic client // (ClientBaustein) on a core scenario's network in Java FILIUS // (ScenarioNetwork) and records what really happens: every frame each card // saw and every line each program wrote into its window (its observers). // // EchoRun // // The stories use the network of tcp-lan (server 192.168.0.10, clients // 192.168.0.20 and .30). The server program runs on .10, switched on // (aktiv) and on its port 55555 before the simulation starts, as a file // loads it; each client program on .20 and .30. The calls come as the // windows make them: verbinden and trennen hand over to the program's // thread, senden runs in the caller's thread (the window's) until it returns. // exchange .20 connects, sends "Hallo" and "Welt", disconnects // closedPort .20 connects to .30, where no server runs // noRoute .20 connects to 10.0.0.1, outside its network, no gateway // notConnected .20 sends without a connection // serverOff connected, the server is switched off, .20 sends; the // server is switched on again, .20 connects and sends // reconnect .20 connects, disconnects, connects again and sends // twoClients .20 and .30 connected at once, each sends, each disconnects // otherPort the server switched off, a second later over to port 7 and // on (as its window does it); .20 connects to 7 and sends, .30 // connects to 55555 (no longer served) import filius.software.clientserver.ClientBaustein; import filius.software.clientserver.ServerBaustein; import java.util.ArrayList; import java.util.List; public class EchoRun { static final String SERVER = "00000000-0000-0000-0000-000000000101"; static final String CLIENT = "00000000-0000-0000-0000-000000000102"; static final String OTHER_CLIENT = "00000000-0000-0000-0000-000000000103"; static final String SERVER_CLASS = "filius.software.clientserver.ServerBaustein"; static final String CLIENT_CLASS = "filius.software.clientserver.ClientBaustein"; static ScenarioNetwork network; static final List events = new ArrayList<>(); static synchronized void event(String who, String what) { events.add(new Object[] { System.currentTimeMillis() - network.start, who, what }); } static void sleepUntil(long milliseconds) throws InterruptedException { long rest = network.start + milliseconds - System.currentTimeMillis(); if (rest > 0) Thread.sleep(rest); } static ClientBaustein client(String nodeId) { return (ClientBaustein) network.system(nodeId).holeSoftware(CLIENT_CLASS); } static void connect(String who, ClientBaustein client, String address, int port) { event(who, "call verbinden " + address + ":" + port); client.setZielIPAdresse(address); client.setZielPort(port); client.verbinden(); } static void send(String who, ClientBaustein client, String text) { event(who, "call senden " + text); client.senden(text); event(who, "returned senden"); } static void disconnect(String who, ClientBaustein client) { event(who, "call trennen"); client.trennen(); } public static void main(String[] args) throws Exception { network = ScenarioNetwork.read(args[0]); String story = args[1]; long end = Long.parseLong(args[2]); network.system(SERVER).installApp(SERVER_CLASS, false); network.system(CLIENT).installApp(CLIENT_CLASS, false); network.system(OTHER_CLIENT).installApp(CLIENT_CLASS, false); ServerBaustein server = (ServerBaustein) network.system(SERVER).holeSoftware(SERVER_CLASS); server.setPort(55555); server.setAktiv(true); // The windows: opened after loading, so they see what follows. server.hinzuBeobachter((observable, data) -> event("server", String.valueOf(data))); client(CLIENT).hinzuBeobachter((observable, data) -> event("client", String.valueOf(data))); client(OTHER_CLIENT).hinzuBeobachter((observable, data) -> event("other", String.valueOf(data))); network.start(); ClientBaustein client = client(CLIENT); ClientBaustein other = client(OTHER_CLIENT); switch (story) { case "exchange": sleepUntil(500); connect("client", client, "192.168.0.10", 55555); sleepUntil(2000); send("client", client, "Hallo"); sleepUntil(4000); send("client", client, "Welt"); sleepUntil(6000); disconnect("client", client); break; case "closedPort": sleepUntil(500); connect("client", client, "192.168.0.30", 55555); break; case "noRoute": sleepUntil(500); connect("client", client, "10.0.0.1", 55555); break; case "notConnected": sleepUntil(500); send("client", client, "Hallo"); break; case "serverOff": sleepUntil(500); connect("client", client, "192.168.0.10", 55555); sleepUntil(2000); event("server", "call setAktiv false"); server.setAktiv(false); sleepUntil(4000); send("client", client, "Hallo"); sleepUntil(6000); event("server", "call setAktiv true"); server.setAktiv(true); sleepUntil(7000); connect("client", client, "192.168.0.10", 55555); sleepUntil(9000); send("client", client, "Welt"); break; case "reconnect": sleepUntil(500); connect("client", client, "192.168.0.10", 55555); sleepUntil(2000); disconnect("client", client); sleepUntil(4000); connect("client", client, "192.168.0.10", 55555); sleepUntil(6000); send("client", client, "Hallo"); break; case "twoClients": sleepUntil(500); connect("client", client, "192.168.0.10", 55555); sleepUntil(1000); connect("other", other, "192.168.0.10", 55555); sleepUntil(2000); send("client", client, "eins"); sleepUntil(3000); send("other", other, "zwei"); sleepUntil(4000); disconnect("client", client); sleepUntil(5000); disconnect("other", other); break; case "otherPort": sleepUntil(500); event("server", "call setAktiv false"); server.setAktiv(false); sleepUntil(1500); event("server", "call setPort 7"); server.setPort(7); event("server", "call setAktiv true"); server.setAktiv(true); sleepUntil(2000); connect("client", client, "192.168.0.10", 7); sleepUntil(4000); send("client", client, "Hallo"); sleepUntil(6000); connect("other", other, "192.168.0.10", 55555); break; default: throw new IllegalArgumentException("unknown story " + story); } sleepUntil(end); ScenarioNetwork.Json out = new ScenarioNetwork.Json(); out.open('{'); network.writeFrames(out); synchronized (EchoRun.class) { out.key("events").open('['); for (Object[] each : events) out.open('[').number((Long) each[0]).string((String) each[1]).string((String) each[2]).close(']'); out.close(']'); } out.close('}'); network.stop(); ScenarioNetwork.write(args[3], out); System.exit(0); } }