Verbesserungsvorschläge zur Struktur einer Client Server Desktop Chat App

dvdlly

Aktives Mitglied
Hallo,

Ich bastle gerade an oben beschriebener App herum. Folgendes ist der aktuelle Code
Java:
import java.io.*;
import java.net.Socket;

public class Controller {
    private final String serverIP;
    private final int serverPort;

    public Controller(String ip, int port){
        serverIP = ip;
        serverPort = port;
    }

    public void sendRequest(Request request){
        try {
            Socket clientSocket = new Socket(this.serverIP, this.serverPort);
            ObjectOutputStream out = new ObjectOutputStream(clientSocket.getOutputStream());
            //ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(clientSocket.getInputStream()));
            out.writeObject(request);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[]args){
        Controller controller = new Controller("localhost",6666);
        Request message = new Request("message");
        message.setAttribute("sender","1");
        message.setAttribute("receiver","2");
        message.setAttribute("id","default");
        message.setAttribute("message","hello friend!");
        controller.sendRequest(message);
        Request quit = new Request("quit");
        controller.sendRequest(quit);
    }
}
Java:
import java.io.*;
import java.net.*;
import java.sql.*;

public class Server {
    private final int port;


    public Server (int port){
        this.port = port;
    }

    public void addMessage(Request request){
        try {
            if (!request.getType().equals("message")){
                throw new RuntimeException("Error, Request Object is not of type message.");
            }
            Connection connection = DriverManager.
                    getConnection("jdbc:mysql://localhost:3306/Whatsapp","david","21da04ma");
            PreparedStatement stmt = connection.prepareStatement("insert into messages (?,?,?,?)");
            stmt.setString(1,"default");
            stmt.setString(2,request.getAttribute("sender"));
            stmt.setString(3,request.getAttribute("receiver"));
            stmt.setString(4,request.getAttribute("message"));
            int i = stmt.executeUpdate();
            System.out.println(i + " rows inserted!");
            connection.close();
        }
        catch (Exception e){
            e.printStackTrace();
        }
    }

    public void addUser(Request request){
        try {
            if (!request.getType().equals("adduser")){
                throw new RuntimeException("Error, Request Object is not of type adduser");
            }
            Connection connection = DriverManager.
                    getConnection("jdbc:mysql://localhost:3306/Whatsapp","nichtdasrichtigepw","123");

            PreparedStatement stmt = connection.prepareStatement("insert into users (?,?,?)");
            stmt.setString(1,"default");
            stmt.setString(2,request.getAttribute("firstname"));
            stmt.setString(3,request.getAttribute("lastname"));
            int i = stmt.executeUpdate();
            System.out.println(i + " rows inserted!");
            connection.close();
        }
        catch (Exception e){
            e.printStackTrace();
        }
    }

    public void start(){
        boolean running = true;
        while (running) {
            try {
                ServerSocket serverSocket = new ServerSocket(this.port);
                Socket clientSocket = serverSocket.accept();
                ObjectOutputStream out = new ObjectOutputStream(clientSocket.getOutputStream());
                ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(clientSocket.getInputStream()));
                Request request = (Request) in.readObject();
                String type = request.getType();

                switch (type) {
                    case "message":
                        this.addMessage(request);
                        System.out.println("addMessage(request) was called.");
                        break;
                    case "adduser":
                        this.addUser(request);
                        break;
                    case "quit":
                        running = false;
                        break;
                    default:
                        break;
                }
                out.close();
                in.close();
                clientSocket.close();
                serverSocket.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }


    public static void main(String[] args){
        Server server = new Server(6666);
        server.start();
    }
}
Java:
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

public class Request implements Serializable {
    private Map<String,String> data = new HashMap<>();
    private final String type;
    String getType(){
        return this.type;
    }
    public Request(String type){
        this.type = type;
    }
    public void setAttribute(String key, String value){
        data.put(key,value);
    }
    public String getAttribute(String key){
        return data.get(key);
    }
}
Wenn ich die beiden main Methoden (erst die vom Server, dann vom Controller) ausführe wird allerdings nichts in die DB eingegeben, weiß jemand woran das liegen könnte?
 
Wird irgendwas auf der Konsole ausgegeben?
Wenn nein, lass dir mal beim swtch-case im default Fall, den String type ausgeben.
 
Sollte nicht. Im Zweifelsfall mal debuggen. Laufen den wirklich auch beide Programme? Nicht das intellij den server abschießt, wenn du den client startest.
 
Java:
while (running) {
            try {
                ServerSocket serverSocket = new ServerSocket(this.port);
                Socket clientSocket = serverSocket.accept();
                ObjectOutputStream out = new ObjectOutputStream(clientSocket.getOutputStream());
                ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(clientSocket.getInputStream()));
du erstellst bei jedem durchlauf einen neuen stream.. ich denke nicht dass das gewollt ist..

und das mit dem switch sieht verdächtig aus...kannst du dir mal den string type ausgeben lassen bevor du in den switch rein gehst
 
Nur mal zur Sicherheit - wenn du beide Programme startest, ist dir bewusst das du auch zwei Konsolen-Fenster hat? (Keine Ahnung wie das bei Intellij ist, bei Eclipse kann ich zwischen denen wechseln).
 
java.sql.SQLException: No suitable driver found for jdbc:mysql://localhost:3306/Whatsapp
addMessage(request) was called.
at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:702)
at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:228)
at de.limdul.javaforum.Server.addMessage(Server.java:24)
at de.limdul.javaforum.Server.start(Server.java:72)
at de.limdul.javaforum.Server.main(Server.java:96)
Bei mir läuft er "sauber" durch (ich war zu faul den JDBC Treiber zu installieren, aber man auf dem Log der Server Anwendung sieht, wird addMessage aufgerufen.
 
Nur mal zur Sicherheit - wenn du beide Programme startest, ist dir bewusst das du auch zwei Konsolen-Fenster hat?
Ja ist mir bewusst, ich weiß nicht wie das intern bei intellij abläuft. Deswegen habe ich gefragt, ob es damit zusammenhängen kann
 
eig sollte es dir die IDE im "Regelfall" nicht versau beuteln... eher mal debuggen und schauen wo es harpert
 
Was übrigens nicht funktioniert ist das "quit" senden, weil du jedes mal einen neuen ServerSocket aufmacht, das zerhaut die Logik des Programms und das quit geht in der Regel verloren. Das wird versucht an den "alten" Server Socket zu schicken.
 
und du läaufst die While einmal durch und schließt sofort wieder die Verbindung ... machst wieder auf usw ... das mit der Schleife und den Objekten darin hoppt noch nich
 
zusätzlich dein "Server" macht im Moment
- Verbindung aufbauen
- Auf Port hören
- Daten auswerten
- Ausgabe
...usw... das is nich schick und führt zu Problemen die du jetzt hast
 
Grundsätzlich - Eins nach dem anderen.

Bist du sicher das die Server Kommunikation funktioniert?
Bist du sicher das die DB Kommunikation funktioniert?

Die Antwort dürfte auf beide Fragen nein sein.

Schritt 1: Eins von beiden rauswerfen - entweder erst mal eine funktionierende DB Kommunikation bauen oder eine funktionierte TCP/IP Kommunikation - ohne jeweils das andere. Dann, wenn das sauber funktioniert den nächsten Schritt.

Wenn du mit der Server-Kommunikation anfängst: Erstmal nur ein Objekt übertragen und schauen was ankommt, nicht direkt schon Logik mit Verwaltung, Switch & Co bauen. Einfach erstmal einen simplen String übertragen. Kommt der an?
 
Die erste Verbindung und somit auch die erste string wird wohl gehn. Aber danach.
Die Verbindung wird vom Client nicht beendet. Es wird einfach wider eine neue aufgebaut. Ohne die alte zubeenden.
 
Java:
      while (running) {
                ServerSocket serverSocket = new ServerSocket(this.port);
                Socket clientSocket = serverSocket.accept();
                ObjectOutputStream out = new ObjectOutputStream(clientSocket.getOutputStream());
                ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(clientSocket.getInputStream()));
                Request request = (Request) in.readObject();
                String type = request.getType();

// ...
            
                out.close();
                in.close();
                clientSocket.close();
                serverSocket.close();}
dsa kann einfach so nicht auf dem Server funktionieren... ich weis nicht wie mans besser erklären kann...
ausser "die Objekte die in der While schleife erzeugt werden passen nicht so ganz"

den user hab ich mir noch gar nicht angesehen..


eine if Abrage dauert um die 0,4 nano sec ... du könntest mal einen Zähler mit laufen lassen wie oft sich der Server neu startet in der Sekunde... und nach der Sekunde dann den Zähler ausgeben lässt

dsa ist wie wenn du eine Antenne aufstellst und sobald sie Fertig ist abreisst weil du ja ne neue Brauchst 😀
 
Ja schon im vorherigen Thread wurde auch schon gesagt das es besser ist das Serversocket vor der while Schleife zu erstellen. Wurde aber als Tipp nicht angenommen.
 
Das sollte ein Scherz sein.

Hier mal ein link wie ein Server und Client aussehen könnten sollten.
Nicht Thread sicher

Auch bei deinem Code Beispiel sollte das Erstellen des serverSocket nicht im der while sein.
 
Das sollte ein Scherz sein.

Hier mal ein link wie ein Server und Client aussehen könnten sollten.
Nicht Thread sicher

Auch bei deinem Code Beispiel sollte das Erstellen des serverSocket nicht im der while sein.
ich hatte doch nur seinen Code kopiert und das im Moment nicht so wichtige raus gelöscht
 

Zurück
Oben