diff --git a/server/src/main/java/ch/zhaw/pm2/multichat/server/Server.java b/server/src/main/java/ch/zhaw/pm2/multichat/server/Server.java index 1edb279..7e31a36 100644 --- a/server/src/main/java/ch/zhaw/pm2/multichat/server/Server.java +++ b/server/src/main/java/ch/zhaw/pm2/multichat/server/Server.java @@ -6,6 +6,8 @@ import java.io.IOException; import java.net.SocketException; import java.util.HashMap; import java.util.Map; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; public class Server { @@ -62,23 +64,34 @@ public class Server { } private void start() { + ReentrantLock mutex = new ReentrantLock(); + Condition nameComplete = mutex.newCondition(); System.out.println("Server started."); try { while (true) { NetworkHandler.NetworkConnection connection = networkServer.waitForConnection(); - ServerConnectionHandler connectionHandler = new ServerConnectionHandler(connection, connections); + ServerConnectionHandler connectionHandler = new ServerConnectionHandler(connection, connections, mutex, nameComplete); new Thread(connectionHandler).start(); - System.out.println(String.format("Connected new Client %s with IP:Port <%s:%d>", - connectionHandler.getUserName(), - connection.getRemoteHost(), - connection.getRemotePort() - )); + mutex.lock(); + try { + nameComplete.await(); + System.out.println(String.format("Connected new Client %s with IP:Port <%s:%d>", + connectionHandler.getUserName(), + connection.getRemoteHost(), + connection.getRemotePort() + )); + } + finally { + mutex.unlock(); + } } } catch(SocketException e) { System.out.println("Server connection terminated"); } catch (IOException e) { System.err.println("Communication error " + e); + } catch (InterruptedException e) { + throw new RuntimeException(e); } // close server System.out.println("Server Stopped."); diff --git a/server/src/main/java/ch/zhaw/pm2/multichat/server/ServerConnectionHandler.java b/server/src/main/java/ch/zhaw/pm2/multichat/server/ServerConnectionHandler.java index 7dd9c82..8e7b4c2 100644 --- a/server/src/main/java/ch/zhaw/pm2/multichat/server/ServerConnectionHandler.java +++ b/server/src/main/java/ch/zhaw/pm2/multichat/server/ServerConnectionHandler.java @@ -11,6 +11,8 @@ import java.util.Map; import java.util.Objects; import java.util.Scanner; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; import static ch.zhaw.pm2.multichat.server.ServerConnectionHandler.State.*; @@ -30,6 +32,10 @@ public class ServerConnectionHandler implements Runnable{ private static final String USER_NONE = ""; private static final String USER_ALL = "*"; + private ReentrantLock mutex; + + private Condition nameComplete; + private String userName = "Anonymous-"+connectionId; private State state = NEW; @@ -43,11 +49,13 @@ public class ServerConnectionHandler implements Runnable{ } public ServerConnectionHandler(NetworkHandler.NetworkConnection connection, - Map registry) { + Map registry, ReentrantLock mutex, Condition nameComplete) { Objects.requireNonNull(connection, "Connection must not be null"); Objects.requireNonNull(registry, "Registry must not be null"); this.connection = connection; this.connectionRegistry = registry; + this.mutex = mutex; + this.nameComplete = nameComplete; } public String getUserName() { @@ -55,28 +63,29 @@ public class ServerConnectionHandler implements Runnable{ } public void startReceiving() { - System.out.println("Starting Connection Handler for new User"); - try { - System.out.println("Start receiving data..."); - while (connection.isAvailable()) { - String data = connection.receive(); - processData(data); + System.out.println("Starting Connection Handler for new User"); + try { + System.out.println("Start receiving data..."); + while (connection.isAvailable()) { + String data = connection.receive(); + processData(data); + } + System.out.println("Stopped recieving data"); + } catch (SocketException e) { + System.out.println("Connection terminated locally"); + connectionRegistry.remove(userName); + System.out.println("Unregistered because client connection terminated: " + userName + " " + e.getMessage()); + } catch (EOFException e) { + System.out.println("Connection terminated by remote"); + connectionRegistry.remove(userName); + System.out.println("Unregistered because client connection terminated: " + userName + " " + e.getMessage()); + } catch (IOException e) { + System.err.println("Communication error: " + e); + } catch (ClassNotFoundException e) { + System.err.println("Received object of unknown type: " + e.getMessage()); } - System.out.println("Stopped recieving data"); - } catch (SocketException e) { - System.out.println("Connection terminated locally"); - connectionRegistry.remove(userName); - System.out.println("Unregistered because client connection terminated: " + userName + " " + e.getMessage()); - } catch (EOFException e) { - System.out.println("Connection terminated by remote"); - connectionRegistry.remove(userName); - System.out.println("Unregistered because client connection terminated: " + userName + " " + e.getMessage()); - } catch(IOException e) { - System.err.println("Communication error: " + e); - } catch(ClassNotFoundException e) { - System.err.println("Received object of unknown type: " + e.getMessage()); - } - System.out.println("Stopping Connection Handler for " + userName); + System.out.println("Stopping Connection Handler for " + userName); + } public void stopReceiving() { @@ -124,7 +133,14 @@ public class ServerConnectionHandler implements Runnable{ if (sender == null || sender.isBlank()) sender = this.userName; if (connectionRegistry.containsKey(sender)) throw new ChatProtocolException("User name already taken: " + sender); - this.userName = sender; + mutex.lock(); + try { + this.userName = sender; + nameComplete.signal(); + } + finally { + mutex.unlock(); + } connectionRegistry.put(userName, this); sendData(USER_NONE, userName, DATA_TYPE_CONFIRM, "Registration successfull for " + userName); this.state = CONNECTED;