Befehlschat

DasDarki

Mitglied
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?
 

DasDarki

Mitglied
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:
Java:
    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:
Java:
    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:
Java:
    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:
Java:
    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

Mitglied
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

Mitglied
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
 

JuKu

Top Contributor
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

Top Contributor
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

Top Contributor
Dann hast du mich falsch verstanden. :D
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. :D
 

Neue Themen


Oben