# Befehlschat



## DasDarki (21. Sep 2016)

Und zwar folgende Vorgeschichte:
Ich bin grade dabei ein CloudSystem für Minecraft Server zu programmieren. Dabei gibt es den Master Server und die Daemons. Der Master kann den Daemons sagen wenn er ein Server brauch, dass die Daemons einen neuen starten sollen. Dies wollte ich über ein Chat lösen, doch habe ich eine Umsetzungslücke und weiß nicht wie ich das machen soll. Ich habe schonmal mit Server und Client Sockets gearbeitet und habe es so auch schonmal versucht, doch das ging nicht. Folgendes: Ich möchte das der Master der Server Socket ist und die Daemons bzw der Daemon der Client ist. Nun möchte ich das der Master dem Client / Daemon irend eine Nachricht schicken kann und darauf dann reagiert, doch wie?


----------



## BRoll (22. Sep 2016)

Schau dir mal JMS an.


----------



## DasDarki (22. Sep 2016)

Ok ich habe noch nie damit gearbeitet


----------



## Tobse (22. Sep 2016)

DasDarki hat gesagt.:


> Ok ich habe noch nie damit gearbeitet


Dann ist jetzt vielleicht das erste mal


----------



## DasDarki (22. Sep 2016)

Ich habe mir jetzt überlegt es doch mit Sockets zu machen, da ich mich mit JMS null auskenne. Aber irgendwie klappt es nicht ganz was ich hier Programmiert habe. Also ich will das der Server dem Client eine Nachricht sendet und der Client darauf hin halt irgendwas macht. Damit im Hintergund des porgrammes noch andere Sachen laufen können habe ich das in Threads gemacht. Hier erstmal die Server Klasse:

```
private ServerSocket server;
    private Socket client;
    private PrintWriter writer;
    private BufferedReader reader;
    public static List<Gamemode> cache = new LinkedList<>();
   
    public CommandServer() {}
   
    public void start(){
        try{
            server = new ServerSocket(3);
            System.out.println(Master.prefix + "Commander started!");
           
            client = server.accept();
            System.out.println(Master.prefix + "Watcher accepted!");
           
            writer = new PrintWriter(client.getOutputStream());
            reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
           
            client.setKeepAlive(true);
           
            Thread thread = new Thread(new Threader(reader));
            thread.start();
           
            startNew(Gamemode.BEISPIEL);
            System.out.print(Master.prefix + "Send StartCommand!");
        }catch(Exception ex){
           
        }
    }
   
    public void startNew(Gamemode gm){
        cache.add(gm);
        writer.write("STARTNEW => " + gm.toString());
        writer.flush();
    }
```

Dann hier den dazugehörigen Thread:

```
private BufferedReader reader;
   
    public Threader(BufferedReader reader) {
        this.reader = reader;
    }

    @Override
    public void run() {
        while(true){
            String s = null;
            try {
                while((s = reader.readLine()) != null){
                    if(s.startsWith("STARTED")){
                        String uuid = s.split(" => ")[1];
                        if(Master.register.getRegisterStatus(UUID.fromString(uuid)) == RegisterStatus.NEW){
                            if(CommandServer.cache.contains(Master.register.getGamemode(UUID.fromString(uuid)))){
                                CommandServer.cache.remove(Master.register.getGamemode(UUID.fromString(uuid)));
                                Master.register.setRegistered(UUID.fromString(uuid));
                                Master.servers.add(Master.register.getGamemode(UUID.fromString(uuid)), Master.register.getPort(UUID.fromString(uuid)));
                            }
                        }
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
```

Jetzt die Client Klasse:

```
private Socket client;
    private PrintWriter writer;
    private BufferedReader reader;
    public static List<Thread> runningServers = new LinkedList<>();
   
    public Watcher() {}
   
    public void start(){
        try {
            client = new Socket("localhost", 3);
            System.out.println(Daemon.prefix + "Watcher started and connected!");
            writer = new PrintWriter(client.getOutputStream());
            reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
           
            client.setKeepAlive(true);
           
            Thread thread = new Thread(new Threader(reader));
            thread.start();
        } catch (IOException e) {
            e.printStackTrace();
        }
       
    }
   
    public void started(String uuid){
        writer.write("STARTED => " + uuid);
        writer.flush();
    }
```
Und ebenso der dazugehörige Thread:

```
private BufferedReader reader;
   
    public Threader(BufferedReader reader) {
        this.reader = reader;
    }
   
    @Override
    public void run() {
        try {
            boolean b = true;
            while (b == true) {
                String s = null;
                while ((s = reader.readLine()) != null) {
                    if(s.startsWith("STARTNEW")){
                        System.out.println(Daemon.prefix + "Recieved!");
                        Gamemode gm = Gamemode.valueOf(s.split(" => ")[1]);
                        ThreadHandler handler = new ThreadHandler(gm);
                        Thread thread = new Thread(handler);
                        thread.start();
                        Watcher.runningServers.add(thread);
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
```
Also der Server sendet anscheinend eine Nachricht ob das Stimmt weiß ich nicht, da der Client diese nicht erhält, jedoch was ich weiß ist das die While Schleife im Thread des Clients nach einem male nicht weiter läuft. Was habe ich falsch?


----------



## DasDarki (23. Sep 2016)

Kann mir jemand helfen?


----------



## Tobse (24. Sep 2016)

Bekommst du denn eine Fehlerausgabe? Schonmal den Debugger versucht?


----------



## DasDarki (24. Sep 2016)

So also den ersten Fehler habe ich selbst gefunden: Falscher Port, man darf ja nur Ports benutzen über 1023, jedoch bekommt der Client immer noch nicht die Nachricht, und nein keine Fehler, debuggen habe ich auch schon versucht...Die Server Console sagt dass der Server die nachricht sendet, zumindest sendet der Server die Consolen nachricht, doch die Recieved nachricht kommt nicht


----------



## DasDarki (24. Sep 2016)

Meine Vermutung ist, dass vielleicht der Master noch nichtmal die Nachricht sendet


----------



## Tobse (24. Sep 2016)

DasDarki hat gesagt.:


> Meine Vermutung ist, dass vielleicht der Master noch nichtmal die Nachricht sendet


Schonmal versucht den OutputStream vom Socket zu flush()en?


----------



## DasDarki (24. Sep 2016)

Habs gelöst:
Und zwar habe ich in der ServerClass in der Methode wo er die nachricht sendet, write benutzt, jedoch musste ich println benutzen


----------



## Major_Sauce (7. Okt 2016)

Ach ja, das hier


DasDarki hat gesagt.:


> }*catch*(Exception ex){
> 
> }


ist das BÖSE in Person.


----------



## JuKu (18. Okt 2016)

Schau dir mal bitte meinen Beitrag hier an:
http://www.java-forum.org/thema/java-chat-server.174028/

Das selbe gilt auch für dieses Projekt.
Erstelle lieber nicht für jede Verbindung einen Thread, sonst wird dein Server schnell in die Knie gehen.
Schau dir mal http://netty.io an.


----------



## Tobse (18. Okt 2016)

JuKu hat gesagt.:


> Erstelle lieber nicht für jede Verbindung einen Thread, sonst wird dein Server schnell in die Knie gehen.


Und was ist die Alternative dazu?! Apache 2 hat für jede Verbindung sogar einen eigenen Prozess.


----------



## JuKu (18. Okt 2016)

Tobse hat gesagt.:


> Und was ist die Alternative dazu?! Apache 2 hat für jede Verbindung sogar einen eigenen Prozess.



Dann liegt dies aber an deiner Apache Konfiguration.
Per Default legt Apache 2 nämlich definitiv (meines Wissens zumindest) nicht für jede Verbindung einen Prozess an - die Prozesserstellung würde schon so lange dauern, dass eine Verbindung nicht so schnell abgearbeitet werden könnte.
Stattdessen nutzt sowohl Apache 2, als auch nginx, einen Thread / Prozess Pool, d.h. die legen gleich am Anfang meinetwegen 8 Threads / Prozesse an, in denen die Anfragen bearbeitet werden (evtl. Threadanzahl = 2 * Anzahl der Cores).
Am besten schaut ihr euch mal die schnellsten Networking Libraries in Java an, z.B. Netty & Grizzly (http://www.infoworld.com/article/26...java-is-fastest-for-server-side-web-apps.html), diese nutzen ebenfalls einen Thread Pool oder einen Executor Service, um die Threads abzuarbeiten. Dies ist auch viel effizienter.


----------



## Tobse (18. Okt 2016)

JuKu hat gesagt.:


> Dann liegt dies aber an deiner Apache Konfiguration.
> Per Default legt Apache 2 nämlich definitiv (meines Wissens zumindest) nicht für jede Verbindung einen Prozess an - die Prozesserstellung würde schon so lange dauern, dass eine Verbindung nicht so schnell abgearbeitet werden könnte.
> Stattdessen nutzt sowohl Apache 2, als auch nginx, einen Thread / Prozess Pool, d.h. die legen gleich am Anfang meinetwegen 8 Threads / Prozesse an, in denen die Anfragen bearbeitet werden (evtl. Threadanzahl = 2 * Anzahl der Cores).
> Am besten schaut ihr euch mal die schnellsten Networking Libraries in Java an, z.B. Netty & Grizzly (http://www.infoworld.com/article/26...java-is-fastest-for-server-side-web-apps.html), diese nutzen ebenfalls einen Thread Pool oder einen Executor Service, um die Threads abzuarbeiten. Dies ist auch viel effizienter.


Dass es ein Pool ist, ändert doch aber nichts daran, dass jede Anfrage in einem eigenen Thread/Prozess ausgeführt wird, oder nicht? Denn die Anfragen warten zu lassen, bis andere fertig sind, ist doch genau das, was vermieden werden soll.


----------



## JuKu (18. Okt 2016)

Dann hast du mich falsch verstanden. 
Natürlich wird die Anfrage nicht im main Thread ausgeführt, aber ich wollte darauf hinaus, dass nicht für jede neue Verbindung nen eigenes (neuer) Thread erstellt wird.


----------



## Tobse (19. Okt 2016)

JuKu hat gesagt.:


> Dann hast du mich falsch verstanden.


Offensichtlich  Sorry wegen dem Wirbel  Cheers


----------

