From 77e9cf616327cc1df54a1cbb27dd0d12e83b36d0 Mon Sep 17 00:00:00 2001 From: Andrin Fassbind Date: Sat, 16 Apr 2022 21:04:51 +0200 Subject: [PATCH 1/4] Attempt to send obj --- .../client/ChatWindowController.java | 4 +- .../client/ClientConnectionHandler.java | 92 ++++++++----------- .../multichat/client/ClientMessageList.java | 8 +- .../multichat/protocol/ConnectionHandler.java | 89 +++++------------- .../zhaw/pm2/multichat/protocol}/Message.java | 17 ++-- .../multichat/protocol/NetworkHandler.java | 6 +- .../server/ServerConnectionHandler.java | 69 ++++++-------- 7 files changed, 109 insertions(+), 176 deletions(-) rename {client/src/main/java/ch/zhaw/pm2/multichat/client => protocol/src/main/java/ch/zhaw/pm2/multichat/protocol}/Message.java (83%) diff --git a/client/src/main/java/ch/zhaw/pm2/multichat/client/ChatWindowController.java b/client/src/main/java/ch/zhaw/pm2/multichat/client/ChatWindowController.java index c09d7ae..8b0e625 100644 --- a/client/src/main/java/ch/zhaw/pm2/multichat/client/ChatWindowController.java +++ b/client/src/main/java/ch/zhaw/pm2/multichat/client/ChatWindowController.java @@ -1,7 +1,9 @@ package ch.zhaw.pm2.multichat.client; +import ch.zhaw.pm2.multichat.protocol.ConnectionHandler; import ch.zhaw.pm2.multichat.protocol.ConnectionHandler.State; import ch.zhaw.pm2.multichat.protocol.ChatProtocolException; +import ch.zhaw.pm2.multichat.protocol.Message; import javafx.application.Platform; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; @@ -231,7 +233,7 @@ public class ChatWindowController { * @param message String to be added as Error */ public void addError(String message) { - messages.addMessage(new Message(Message.MessageType.ERROR, null, null, message)); + messages.addMessage(new Message(ConnectionHandler.DATA_TYPE.DATA_TYPE_ERROR, null, null, message)); } /** diff --git a/client/src/main/java/ch/zhaw/pm2/multichat/client/ClientConnectionHandler.java b/client/src/main/java/ch/zhaw/pm2/multichat/client/ClientConnectionHandler.java index 2ed34e5..28bcc0d 100644 --- a/client/src/main/java/ch/zhaw/pm2/multichat/client/ClientConnectionHandler.java +++ b/client/src/main/java/ch/zhaw/pm2/multichat/client/ClientConnectionHandler.java @@ -2,6 +2,7 @@ package ch.zhaw.pm2.multichat.client; import ch.zhaw.pm2.multichat.protocol.ChatProtocolException; import ch.zhaw.pm2.multichat.protocol.ConnectionHandler; +import ch.zhaw.pm2.multichat.protocol.Message; import ch.zhaw.pm2.multichat.protocol.NetworkHandler; import javafx.beans.property.SimpleIntegerProperty; import javafx.beans.property.SimpleObjectProperty; @@ -122,7 +123,7 @@ public class ClientConnectionHandler extends ConnectionHandler implements Runnab try { System.out.println("Start receiving data..."); while (getConnection().isAvailable()) { - String data = getConnection().receive(); + Message data = (Message) getConnection().receive(); processData(data); } System.out.println("Stopped receiving data"); @@ -162,95 +163,76 @@ public class ClientConnectionHandler extends ConnectionHandler implements Runnab * * @param data that is received in a form of a String and then used depending on its determined cause. */ - private void processData(String data) { - try { - Scanner scanner = new Scanner(data); - StringBuilder sender = new StringBuilder(); - StringBuilder receiver = new StringBuilder(); - StringBuilder type = new StringBuilder(); - StringBuilder payload = new StringBuilder(); - super.processData(scanner, sender, receiver, type, payload); - - // dispatch operation based on type parameter - if (type.toString().equals(getDataTypeConnect())) { - System.err.println("Illegal connect request from server"); - } else if (type.toString().equals(getDataTypeConfirm())) { - caseConfirm(sender.toString(), receiver.toString(), payload.toString()); - } else if (type.toString().equals(getDataTypeDisconnect())) { - caseDisconnect(sender.toString(), receiver.toString(), payload.toString()); - } else if (type.toString().equals(getDataTypeMessage())) { - caseMessage(sender.toString(), receiver.toString(), payload.toString()); - } else if (type.toString().equals(getDataTypeError())) { - caseError(sender.toString(), receiver.toString(), payload.toString()); - } else { - System.out.println("Unknown data type received: " + type); - } - } catch (ChatProtocolException e) { - System.err.println("Error while processing data: " + e.getMessage()); - sendData(USER_NONE, userName.get(), getDataTypeError(), e.getMessage()); + private void processData(Message data) { + // dispatch operation based on type parameter + if (data.getType() == DATA_TYPE.DATA_TYPE_CONNECT) { + System.err.println("Illegal connect request from server"); + } else if (data.getType() == DATA_TYPE.DATA_TYPE_CONFIRM) { + caseConfirm(data); + } else if (data.getType() == DATA_TYPE.DATA_TYPE_DISCONNECT) { + caseDisconnect(data); + } else if (data.getType() == DATA_TYPE.DATA_TYPE_MESSAGE) { + caseMessage(data); + } else if (data.getType() == DATA_TYPE.DATA_TYPE_ERROR) { + caseError(data); + } else { + System.out.println("Unknown data type received: " + data.getType()); } } - private void caseConfirm(String sender, String receiver, String payload) { + private void caseConfirm(Message data) { if (state.get() == CONFIRM_CONNECT) { - this.userName.set(receiver); + this.userName.set(data.getReceiver()); this.serverPort.set(getConnection().getRemotePort()); this.serverAddress.set(getConnection().getRemoteHost()); - messages.addMessage(new Message(Message.MessageType.INFO, sender, receiver, payload)); - System.out.println("CONFIRM: " + payload); + messages.addMessage(data); + System.out.println("CONFIRM: " + data.getText()); this.setState(CONNECTED); } else if (state.get() == CONFIRM_DISCONNECT) { - messages.addMessage(new Message(Message.MessageType.INFO, sender, receiver, payload)); - System.out.println("CONFIRM: " + payload); + messages.addMessage(data); + System.out.println("CONFIRM: " + data.getText()); this.setState(DISCONNECTED); } else { - System.err.println("Got unexpected confirm message: " + payload); + System.err.println("Got unexpected confirm message: " + data.getText()); } } /** * Initiates the disconnect sequence and sends the message with all its info. * - * @param sender the sender name of the message - * @param receiver the receiver name of the message - * @param payload the added payload that corresponds to the message + * @param data Data which has been transmitted */ - private void caseDisconnect(String sender, String receiver, String payload) { + private void caseDisconnect(Message data) { if (state.get() == DISCONNECTED) { - System.out.println("DISCONNECT: Already in disconnected: " + payload); + System.out.println("DISCONNECT: Already in disconnected: " + data.getText()); return; } - messages.addMessage(new Message(Message.MessageType.INFO, sender, receiver, payload)); - System.out.println("DISCONNECT: " + payload); + messages.addMessage(data); + System.out.println("DISCONNECT: " + data.getText()); this.setState(DISCONNECTED); } /** * Initiates the procedure to send a new message and sends one as such. - * - * @param sender the sender name of the message - * @param receiver the receiver name of the message - * @param payload the added payload that corresponds to the message + * @param data Data which has been transmitted */ - private void caseMessage(String sender, String receiver, String payload) { + private void caseMessage(Message data) { if (state.get() != CONNECTED) { - System.out.println("MESSAGE: Illegal state " + state + " for message: " + payload); + System.out.println("MESSAGE: Illegal state " + state + " for message: " + data.getText()); return; } - messages.addMessage(new Message(Message.MessageType.MESSAGE, sender, receiver, payload)); - System.out.println("MESSAGE: From " + sender + " to " + receiver + ": " + payload); + messages.addMessage(data); + System.out.println("MESSAGE: From " + data.getSender() + " to " + data.getReceiver() + ": " + data.getText()); } /** * Stores the message as an error message and displays it as such as well. * - * @param sender the sender name of the message - * @param receiver the receiver name of the message - * @param payload the added payload that corresponds to the message + * @param data Data which has been transmitted */ - private void caseError(String sender, String receiver, String payload) { - messages.addMessage(new Message(Message.MessageType.ERROR, sender, receiver, payload)); - System.out.println("ERROR: " + payload); + private void caseError(Message data) { + messages.addMessage(data); + System.out.println("ERROR: " + data.getText()); } /** diff --git a/client/src/main/java/ch/zhaw/pm2/multichat/client/ClientMessageList.java b/client/src/main/java/ch/zhaw/pm2/multichat/client/ClientMessageList.java index 276f39e..9061a4a 100644 --- a/client/src/main/java/ch/zhaw/pm2/multichat/client/ClientMessageList.java +++ b/client/src/main/java/ch/zhaw/pm2/multichat/client/ClientMessageList.java @@ -1,5 +1,7 @@ package ch.zhaw.pm2.multichat.client; +import ch.zhaw.pm2.multichat.protocol.ConnectionHandler; +import ch.zhaw.pm2.multichat.protocol.Message; import javafx.beans.property.SimpleBooleanProperty; import java.util.ArrayList; @@ -35,10 +37,10 @@ public class ClientMessageList { for (Message message : messages) { if (showAll || message.matchesFilter(filter)) { switch (message.getType()) { - case MESSAGE -> + case DATA_TYPE_MESSAGE -> result.append(String.format("[%s -> %s] %s\n", message.getSender(), message.getReceiver(), message.getText())); - case ERROR -> result.append(String.format("[ERROR] %s\n", message.getText())); - case INFO -> result.append(String.format("[INFO] %s\n", message.getText())); + case DATA_TYPE_ERROR -> result.append(String.format("[ERROR] %s\n", message.getText())); + case DATA_TYPE_CONFIRM, DATA_TYPE_DISCONNECT, DATA_TYPE_CONNECT -> result.append(String.format("[INFO] %s\n", message.getText())); default -> result.append(String.format("[ERROR] %s\n", "Unexpected message type: " + message.getType())); } diff --git a/protocol/src/main/java/ch/zhaw/pm2/multichat/protocol/ConnectionHandler.java b/protocol/src/main/java/ch/zhaw/pm2/multichat/protocol/ConnectionHandler.java index 6cc5450..ae586b0 100644 --- a/protocol/src/main/java/ch/zhaw/pm2/multichat/protocol/ConnectionHandler.java +++ b/protocol/src/main/java/ch/zhaw/pm2/multichat/protocol/ConnectionHandler.java @@ -8,18 +8,11 @@ import java.util.Scanner; /** * This abstract class is the superclass for ClientConnectionHandler and ServerConnectionHandler * It offers the DATA_TYPE Strings and a {@link State} enum for all valid connection states. - * Shared methods are implemented in this class as well {@link ConnectionHandler#sendData(String, String, String, String)} {@link ConnectionHandler#processData(Scanner, StringBuilder, StringBuilder, StringBuilder, StringBuilder)} + * Shared methods are implemented in this class as well {@link ConnectionHandler#sendData(String, String, DATA_TYPE, String)} {@link ConnectionHandler#processData(Scanner, StringBuilder, StringBuilder, StringBuilder, StringBuilder)} */ public abstract class ConnectionHandler { private NetworkHandler.NetworkConnection connection; - // Data types used for the Chat Protocol - private static final String DATA_TYPE_CONNECT = "CONNECT"; - private static final String DATA_TYPE_CONFIRM = "CONFIRM"; - private static final String DATA_TYPE_DISCONNECT = "DISCONNECT"; - private static final String DATA_TYPE_MESSAGE = "MESSAGE"; - private static final String DATA_TYPE_ERROR = "ERROR"; - public static final String USER_NONE = ""; public static final String USER_ALL = "*"; @@ -28,39 +21,43 @@ public abstract class ConnectionHandler { NEW, CONFIRM_CONNECT, CONNECTED, CONFIRM_DISCONNECT, DISCONNECTED, ERROR; } - /** - * @return {@link ConnectionHandler#DATA_TYPE_CONNECT} - */ - public static String getDataTypeConnect() { - return DATA_TYPE_CONNECT; + public enum DATA_TYPE { + DATA_TYPE_CONNECT, DATA_TYPE_CONFIRM, DATA_TYPE_DISCONNECT,DATA_TYPE_MESSAGE,DATA_TYPE_ERROR } /** - * @return {@link ConnectionHandler#DATA_TYPE_CONFIRM} + * @return {@link DATA_TYPE} */ - public static String getDataTypeConfirm() { - return DATA_TYPE_CONFIRM; + public static DATA_TYPE getDataTypeConnect() { + return DATA_TYPE.DATA_TYPE_CONNECT; } /** - * @return {@link ConnectionHandler#DATA_TYPE_DISCONNECT} + * @return {@link DATA_TYPE} */ - public static String getDataTypeDisconnect() { - return DATA_TYPE_DISCONNECT; + public static DATA_TYPE getDataTypeConfirm() { + return DATA_TYPE.DATA_TYPE_CONFIRM; } /** - * @return {@link ConnectionHandler#DATA_TYPE_MESSAGE + * @return {@link DATA_TYPE} */ - public static String getDataTypeMessage() { - return DATA_TYPE_MESSAGE; + public static DATA_TYPE getDataTypeDisconnect() { + return DATA_TYPE.DATA_TYPE_DISCONNECT; } /** - * @return {@link ConnectionHandler#DATA_TYPE_ERROR} + * @return {@link DATA_TYPE} */ - public static String getDataTypeError() { - return DATA_TYPE_ERROR; + public static DATA_TYPE getDataTypeMessage() { + return DATA_TYPE.DATA_TYPE_MESSAGE; + } + + /** + * @return {@link DATA_TYPE} + */ + public static DATA_TYPE getDataTypeError() { + return DATA_TYPE.DATA_TYPE_ERROR; } /** @@ -79,40 +76,6 @@ public abstract class ConnectionHandler { this.connection = connection; } - /** - * This method reads the data when a ConnectionHandler receives it. It tries to read out the sender, receiver, type and payload. - * If the data does not contain the expected number of lines, it throws a {@link ChatProtocolException} - * - * @param scanner to read data - * @param sender of the data - * @param receiver for the data - * @param type of data - * @param payload the data sent - * @throws ChatProtocolException if the data does not contain the expected number of lines - */ - protected void processData(Scanner scanner, StringBuilder sender, StringBuilder receiver, StringBuilder type, StringBuilder payload) throws ChatProtocolException { - // parse data content - if (scanner.hasNextLine()) { - sender.append(scanner.nextLine()); - } else if (scanner.hasNextLine()) { - receiver.append(scanner.nextLine()); - } else { - throw new ChatProtocolException("No Sender found"); - } - if (scanner.hasNextLine()) { - receiver.append(scanner.nextLine()); - } else { - throw new ChatProtocolException("No Reciever found"); - } - if (scanner.hasNextLine()) { - type.append(scanner.nextLine()); - } else { - throw new ChatProtocolException("No Type found"); - } - if (scanner.hasNextLine()) { - payload.append(scanner.nextLine()); - } - } /** * This method gets called to send data via the socket defined in the {@link NetworkHandler.NetworkConnection} @@ -122,14 +85,10 @@ public abstract class ConnectionHandler { * @param type of the data * @param payload of the data */ - protected void sendData(String sender, String receiver, String type, String payload) { + protected void sendData(String sender, String receiver, DATA_TYPE type, String payload) { if (connection.isAvailable()) { - String data = sender + "\n" + - receiver + "\n" + - type + "\n" + - payload + "\n"; try { - connection.send(data); + connection.send(new Message(type,sender,receiver,payload)); } catch (SocketException e) { System.err.println("Connection closed: " + e.getMessage()); } catch (EOFException e) { diff --git a/client/src/main/java/ch/zhaw/pm2/multichat/client/Message.java b/protocol/src/main/java/ch/zhaw/pm2/multichat/protocol/Message.java similarity index 83% rename from client/src/main/java/ch/zhaw/pm2/multichat/client/Message.java rename to protocol/src/main/java/ch/zhaw/pm2/multichat/protocol/Message.java index 1745623..0c5976c 100644 --- a/client/src/main/java/ch/zhaw/pm2/multichat/client/Message.java +++ b/protocol/src/main/java/ch/zhaw/pm2/multichat/protocol/Message.java @@ -1,11 +1,11 @@ -package ch.zhaw.pm2.multichat.client; +package ch.zhaw.pm2.multichat.protocol; /** * A Message object represents one Message of a client. Can be stored in ClientMessageList. */ public class Message { - private final MessageType type; - private final String sender; + private final ConnectionHandler.DATA_TYPE type; + private String sender; private final String receiver; private final String text; @@ -17,7 +17,7 @@ public class Message { * @param receiver The User who should receive the message. * @param text The Text of the message. */ - public Message(MessageType type, String sender, String receiver, String text) { + public Message(ConnectionHandler.DATA_TYPE type, String sender, String receiver, String text) { this.type = type; this.sender = sender; this.receiver = receiver; @@ -39,7 +39,7 @@ public class Message { /** * @return The type of the message. */ - public MessageType getType() { + public ConnectionHandler.DATA_TYPE getType() { return type; } @@ -64,10 +64,7 @@ public class Message { return text; } - /** - * Enumeration of Message Types. - */ - public enum MessageType { - INFO, MESSAGE, ERROR; + public void setSender(String sender) { + this.sender = sender; } } diff --git a/protocol/src/main/java/ch/zhaw/pm2/multichat/protocol/NetworkHandler.java b/protocol/src/main/java/ch/zhaw/pm2/multichat/protocol/NetworkHandler.java index 6c58849..20d20ad 100644 --- a/protocol/src/main/java/ch/zhaw/pm2/multichat/protocol/NetworkHandler.java +++ b/protocol/src/main/java/ch/zhaw/pm2/multichat/protocol/NetworkHandler.java @@ -38,7 +38,7 @@ import java.util.Objects; * on the client side, usually the result is displayed to the user). After processing is finished the * process calls {@link NetworkConnection#receive()} again to wait for the next request. * - *
  • sending data: call {@link NetworkConnection#send(Serializable data)}, which sends the given data + *
  • sending data: call {@link NetworkConnection#send(Message)}, which sends the given data * object to the remote side. The method returns as soon the object has been transmitted. * Important: {@link NetworkConnection} is not thread safe, therefore make sure that only one thread * at a time is sending data.
  • @@ -270,7 +270,7 @@ public class NetworkHandler { * on the client side, usually the result is displayed to the user). After processing is finished the * process calls {@link NetworkConnection#receive()} again to wait for the next request. * - *
  • sending data: call {@link NetworkConnection#send(Serializable data)}, which sends the given data + *
  • sending data: call {@link NetworkConnection#send(Message)}, which sends the given data * object to the remote side. The method returns as soon the object has been transmitted. * Important: {@link NetworkConnection} is not thread safe, therefore make sure that only one thread * at a time is sending data. @@ -305,7 +305,7 @@ public class NetworkHandler { * @param data data object of type T to be submitted through the connection. * @throws IOException if an error occurs (e.g. connection interrupted while sending, ...) */ - public synchronized void send(T data) throws IOException { + public synchronized void send(Message data) throws IOException { ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream()); outputStream.writeObject(data); } 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 d246c66..0dda2e7 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 @@ -5,6 +5,7 @@ import ch.zhaw.pm2.multichat.protocol.ConnectionHandler; import static ch.zhaw.pm2.multichat.protocol.ConnectionHandler.State.*; +import ch.zhaw.pm2.multichat.protocol.Message; import ch.zhaw.pm2.multichat.protocol.NetworkHandler; import java.io.EOFException; @@ -84,7 +85,7 @@ public class ServerConnectionHandler extends ConnectionHandler implements Runnab try { System.out.println("Start receiving data..."); while (getConnection().isAvailable() && !(state == ERROR)) { - String data = getConnection().receive(); + Message data = getConnection().receive(); processData(data); } System.out.println("Stopped receiving data"); @@ -136,28 +137,21 @@ public class ServerConnectionHandler extends ConnectionHandler implements Runnab * * @param data received by the server */ - private void processData(String data) { + private void processData(Message data) { try { - Scanner scanner = new Scanner(data); - StringBuilder sender = new StringBuilder(); - StringBuilder receiver = new StringBuilder(); - StringBuilder type = new StringBuilder(); - StringBuilder payload = new StringBuilder(); - super.processData(scanner, sender, receiver, type, payload); - // dispatch operation based on type parameter - if (type.toString().equals(getDataTypeConnect())) { - caseConnect(sender.toString()); - } else if (type.toString().equals(getDataTypeConfirm())) { + if (data.getType() == DATA_TYPE.DATA_TYPE_CONNECT) { + caseConnect(data); + } else if (data.getType() == DATA_TYPE.DATA_TYPE_CONFIRM) { System.out.println("Not expecting to receive a CONFIRM request from client"); - } else if (type.toString().equals(getDataTypeDisconnect())) { + } else if (data.getType() == DATA_TYPE.DATA_TYPE_DISCONNECT) { caseDisconnect(); - } else if (type.toString().equals(getDataTypeMessage())) { - caseMessage(sender.toString(), receiver.toString(), type.toString(), payload.toString()); - } else if (type.toString().equals(getDataTypeError())) { - System.err.println("Received error from client (" + sender + "): " + payload); + } else if (data.getType() == DATA_TYPE.DATA_TYPE_MESSAGE) { + caseMessage(data); + } else if (data.getType() == DATA_TYPE.DATA_TYPE_ERROR) { + System.err.println("Received error from client (" + data.getSender() + "): " + data.getText()); } else { - System.err.println("Unknown data type received: " + type); + System.err.println("Unknown data type received: " + data.getType()); } } catch (ChatProtocolException e) { @@ -167,25 +161,25 @@ public class ServerConnectionHandler extends ConnectionHandler implements Runnab } /** - * This method is called by method {@link ServerConnectionHandler#processData(String)} + * This method is called by method {@link ServerConnectionHandler#processData(Message)} * Checks if username is valid. if valid sends response to client with confirmation. * - * @param sender of the payload + * @param data sent * @throws ChatProtocolException if username not valid */ - private void caseConnect(String sender) throws ChatProtocolException { + private void caseConnect(Message data) throws ChatProtocolException { if (this.state != NEW) throw new ChatProtocolException("Illegal state for connect request: " + state); - if (sender.isBlank()) sender = this.userName; + if (data.getSender().isBlank()) data.setSender(this.userName); //if username not valid - if (connectionRegistry.containsKey(sender)) { + if (connectionRegistry.containsKey(data.getSender())) { state = ERROR; System.out.println(String.format("Connecting failed for new Client with IP:Port <%s:%d>.\nReason: Name already taken.", getConnection().getRemoteHost(), getConnection().getRemotePort())); - throw new ChatProtocolException("User name already taken: " + sender); + throw new ChatProtocolException("User name already taken: " + data.getSender()); } //if username valid - this.userName = sender; + this.userName = data.getSender(); connectionRegistry.put(userName, this); sendData(USER_NONE, userName, getDataTypeConfirm(), "Registration successful for " + userName); this.state = CONNECTED; @@ -196,7 +190,7 @@ public class ServerConnectionHandler extends ConnectionHandler implements Runnab } /** - * This method is called by method {@link ServerConnectionHandler#processData(String)} + * This method is called by method {@link ServerConnectionHandler#processData(Message)} * Disconnects connection by removing connection from registry and calling method {@link ServerConnectionHandler#stopReceiving()} to terminate socket. * * @throws ChatProtocolException if state already DISCONNECTED. @@ -213,30 +207,27 @@ public class ServerConnectionHandler extends ConnectionHandler implements Runnab } /** - * This method is called by method {@link ServerConnectionHandler#processData(String)} + * This method is called by method {@link ServerConnectionHandler#processData(Message)} * Checks if broadcast or unicast. Sends data accordingly * - * @param sender who sent data - * @param receiver to receive data - * @param type of message - * @param payload data to transmit + * @param data to transmit * @throws ChatProtocolException if state not equal to CONNECT */ - private void caseMessage(String sender, String receiver, String type, String payload) throws ChatProtocolException { + private void caseMessage(Message data) throws ChatProtocolException { if (state != CONNECTED) throw new ChatProtocolException("Illegal state for message request: " + state); - if (USER_ALL.equals(receiver)) { + if (USER_ALL.equals(data.getReceiver())) { for (ServerConnectionHandler handler : connectionRegistry.values()) { - handler.sendData(sender, receiver, type, payload); + handler.sendData(data.getSender(), data.getReceiver(), data.getType(), data.getText()); } } else { - ServerConnectionHandler handler = connectionRegistry.get(receiver); + ServerConnectionHandler handler = connectionRegistry.get(data.getReceiver()); if (handler != null) { - handler.sendData(sender, receiver, type, payload); - if (!receiver.equals(sender)) { - sendData(sender, receiver, type, payload); //send message to sender if it's a direct message and sender is not receiver. + handler.sendData(data.getSender(), data.getReceiver(), data.getType(), data.getText()); + if (!data.getReceiver().equals(data.getSender())) { + sendData(data.getSender(), data.getReceiver(), data.getType(), data.getText()); //send message to sender if it's a direct message and sender is not receiver. } } else { - this.sendData(USER_NONE, userName, getDataTypeError(), "Unknown User: " + receiver); + this.sendData(USER_NONE, userName, getDataTypeError(), "Unknown User: " + data.getReceiver()); } } } From 6498b8ab33b6817715f12dc3d9a67f6060352aeb Mon Sep 17 00:00:00 2001 From: Andrin Fassbind Date: Sat, 16 Apr 2022 21:12:55 +0200 Subject: [PATCH 2/4] fixed #49 --- .../ch/zhaw/pm2/multichat/client/ClientConnectionHandler.java | 2 +- .../src/main/java/ch/zhaw/pm2/multichat/protocol/Message.java | 4 +++- .../java/ch/zhaw/pm2/multichat/protocol/NetworkHandler.java | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/client/src/main/java/ch/zhaw/pm2/multichat/client/ClientConnectionHandler.java b/client/src/main/java/ch/zhaw/pm2/multichat/client/ClientConnectionHandler.java index 28bcc0d..eab747b 100644 --- a/client/src/main/java/ch/zhaw/pm2/multichat/client/ClientConnectionHandler.java +++ b/client/src/main/java/ch/zhaw/pm2/multichat/client/ClientConnectionHandler.java @@ -123,7 +123,7 @@ public class ClientConnectionHandler extends ConnectionHandler implements Runnab try { System.out.println("Start receiving data..."); while (getConnection().isAvailable()) { - Message data = (Message) getConnection().receive(); + Message data = getConnection().receive(); processData(data); } System.out.println("Stopped receiving data"); diff --git a/protocol/src/main/java/ch/zhaw/pm2/multichat/protocol/Message.java b/protocol/src/main/java/ch/zhaw/pm2/multichat/protocol/Message.java index 0c5976c..d64ee80 100644 --- a/protocol/src/main/java/ch/zhaw/pm2/multichat/protocol/Message.java +++ b/protocol/src/main/java/ch/zhaw/pm2/multichat/protocol/Message.java @@ -1,9 +1,11 @@ package ch.zhaw.pm2.multichat.protocol; +import java.io.Serializable; + /** * A Message object represents one Message of a client. Can be stored in ClientMessageList. */ -public class Message { +public class Message implements Serializable { private final ConnectionHandler.DATA_TYPE type; private String sender; private final String receiver; diff --git a/protocol/src/main/java/ch/zhaw/pm2/multichat/protocol/NetworkHandler.java b/protocol/src/main/java/ch/zhaw/pm2/multichat/protocol/NetworkHandler.java index 20d20ad..02c5b09 100644 --- a/protocol/src/main/java/ch/zhaw/pm2/multichat/protocol/NetworkHandler.java +++ b/protocol/src/main/java/ch/zhaw/pm2/multichat/protocol/NetworkHandler.java @@ -320,9 +320,9 @@ public class NetworkHandler { * @throws IOException if an error occours. (e.g. terminated locally/remotely) see above. * @throws ClassNotFoundException if the data object received does not match any class in the local classpath */ - public T receive() throws IOException, ClassNotFoundException { + public Message receive() throws IOException, ClassNotFoundException { ObjectInputStream inputStream = new ObjectInputStream(this.socket.getInputStream()); - return (T) inputStream.readObject(); + return (Message) inputStream.readObject(); } /** From a189fedd7633c4bc69c6789cd0fc3f886eba429b Mon Sep 17 00:00:00 2001 From: Andrin Fassbind Date: Sat, 16 Apr 2022 22:01:59 +0200 Subject: [PATCH 3/4] fixed #49 clean up --- .../main/java/ch/zhaw/pm2/multichat/protocol/Message.java | 3 --- .../zhaw/pm2/multichat/server/ServerConnectionHandler.java | 5 +++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/protocol/src/main/java/ch/zhaw/pm2/multichat/protocol/Message.java b/protocol/src/main/java/ch/zhaw/pm2/multichat/protocol/Message.java index d64ee80..9509b0f 100644 --- a/protocol/src/main/java/ch/zhaw/pm2/multichat/protocol/Message.java +++ b/protocol/src/main/java/ch/zhaw/pm2/multichat/protocol/Message.java @@ -66,7 +66,4 @@ public class Message implements Serializable { return text; } - public void setSender(String sender) { - this.sender = sender; - } } 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 0dda2e7..0dc8aee 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 @@ -169,7 +169,6 @@ public class ServerConnectionHandler extends ConnectionHandler implements Runnab */ private void caseConnect(Message data) throws ChatProtocolException { if (this.state != NEW) throw new ChatProtocolException("Illegal state for connect request: " + state); - if (data.getSender().isBlank()) data.setSender(this.userName); //if username not valid if (connectionRegistry.containsKey(data.getSender())) { state = ERROR; @@ -179,7 +178,9 @@ public class ServerConnectionHandler extends ConnectionHandler implements Runnab throw new ChatProtocolException("User name already taken: " + data.getSender()); } //if username valid - this.userName = data.getSender(); + if (!data.getSender().isBlank()) { + this.userName = data.getSender(); + } connectionRegistry.put(userName, this); sendData(USER_NONE, userName, getDataTypeConfirm(), "Registration successful for " + userName); this.state = CONNECTED; From 40e3e146662143c6f90c5779e09772aab39bb27b Mon Sep 17 00:00:00 2001 From: Andrin Fassbind Date: Sat, 16 Apr 2022 22:09:56 +0200 Subject: [PATCH 4/4] fixed #49 clean up --- .../pm2/multichat/client/ChatWindowController.java | 1 - .../pm2/multichat/client/ClientConnectionHandler.java | 5 +++-- .../zhaw/pm2/multichat/client/ClientMessageList.java | 7 +++---- .../zhaw/pm2/multichat/protocol/ConnectionHandler.java | 10 +++++----- .../java/ch/zhaw/pm2/multichat/protocol/Message.java | 2 +- .../main/java/ch/zhaw/pm2/multichat/server/Server.java | 2 +- .../pm2/multichat/server/ServerConnectionHandler.java | 6 ++---- 7 files changed, 15 insertions(+), 18 deletions(-) diff --git a/client/src/main/java/ch/zhaw/pm2/multichat/client/ChatWindowController.java b/client/src/main/java/ch/zhaw/pm2/multichat/client/ChatWindowController.java index 8b0e625..df225eb 100644 --- a/client/src/main/java/ch/zhaw/pm2/multichat/client/ChatWindowController.java +++ b/client/src/main/java/ch/zhaw/pm2/multichat/client/ChatWindowController.java @@ -242,7 +242,6 @@ public class ChatWindowController { class WindowCloseHandler implements EventHandler { /** - * * @param event the event which occurred when Windows is closed */ public void handle(WindowEvent event) { diff --git a/client/src/main/java/ch/zhaw/pm2/multichat/client/ClientConnectionHandler.java b/client/src/main/java/ch/zhaw/pm2/multichat/client/ClientConnectionHandler.java index eab747b..6fa0034 100644 --- a/client/src/main/java/ch/zhaw/pm2/multichat/client/ClientConnectionHandler.java +++ b/client/src/main/java/ch/zhaw/pm2/multichat/client/ClientConnectionHandler.java @@ -50,8 +50,8 @@ public class ClientConnectionHandler extends ConnectionHandler implements Runnab * Called to initialize the ClientConnectionHandler when trying to start a connection * * @param serverAddress to connect to - * @param serverPort to connect to - * @param userName to connect as + * @param serverPort to connect to + * @param userName to connect as * @throws IOException if connection to Server not possible */ public void initialize(String serverAddress, int serverPort, String userName) throws IOException { @@ -214,6 +214,7 @@ public class ClientConnectionHandler extends ConnectionHandler implements Runnab /** * Initiates the procedure to send a new message and sends one as such. + * * @param data Data which has been transmitted */ private void caseMessage(Message data) { diff --git a/client/src/main/java/ch/zhaw/pm2/multichat/client/ClientMessageList.java b/client/src/main/java/ch/zhaw/pm2/multichat/client/ClientMessageList.java index 9061a4a..6151e97 100644 --- a/client/src/main/java/ch/zhaw/pm2/multichat/client/ClientMessageList.java +++ b/client/src/main/java/ch/zhaw/pm2/multichat/client/ClientMessageList.java @@ -17,6 +17,7 @@ public class ClientMessageList { /** * Adds a new message to ArrayList and also informs Listener. + * * @param message that should be added */ public void addMessage(Message message) { @@ -37,12 +38,10 @@ public class ClientMessageList { for (Message message : messages) { if (showAll || message.matchesFilter(filter)) { switch (message.getType()) { - case DATA_TYPE_MESSAGE -> - result.append(String.format("[%s -> %s] %s\n", message.getSender(), message.getReceiver(), message.getText())); + case DATA_TYPE_MESSAGE -> result.append(String.format("[%s -> %s] %s\n", message.getSender(), message.getReceiver(), message.getText())); case DATA_TYPE_ERROR -> result.append(String.format("[ERROR] %s\n", message.getText())); case DATA_TYPE_CONFIRM, DATA_TYPE_DISCONNECT, DATA_TYPE_CONNECT -> result.append(String.format("[INFO] %s\n", message.getText())); - default -> - result.append(String.format("[ERROR] %s\n", "Unexpected message type: " + message.getType())); + default -> result.append(String.format("[ERROR] %s\n", "Unexpected message type: " + message.getType())); } } } diff --git a/protocol/src/main/java/ch/zhaw/pm2/multichat/protocol/ConnectionHandler.java b/protocol/src/main/java/ch/zhaw/pm2/multichat/protocol/ConnectionHandler.java index ae586b0..1878f62 100644 --- a/protocol/src/main/java/ch/zhaw/pm2/multichat/protocol/ConnectionHandler.java +++ b/protocol/src/main/java/ch/zhaw/pm2/multichat/protocol/ConnectionHandler.java @@ -3,12 +3,11 @@ package ch.zhaw.pm2.multichat.protocol; import java.io.EOFException; import java.io.IOException; import java.net.SocketException; -import java.util.Scanner; /** * This abstract class is the superclass for ClientConnectionHandler and ServerConnectionHandler - * It offers the DATA_TYPE Strings and a {@link State} enum for all valid connection states. - * Shared methods are implemented in this class as well {@link ConnectionHandler#sendData(String, String, DATA_TYPE, String)} {@link ConnectionHandler#processData(Scanner, StringBuilder, StringBuilder, StringBuilder, StringBuilder)} + * It offers the DATA_TYPE for message and a {@link State} enum for all valid connection states. + * Shared methods are implemented in this class as well {@link ConnectionHandler#sendData(String, String, DATA_TYPE, String)} */ public abstract class ConnectionHandler { private NetworkHandler.NetworkConnection connection; @@ -21,8 +20,9 @@ public abstract class ConnectionHandler { NEW, CONFIRM_CONNECT, CONNECTED, CONFIRM_DISCONNECT, DISCONNECTED, ERROR; } + // DATA_TYPE of the messages public enum DATA_TYPE { - DATA_TYPE_CONNECT, DATA_TYPE_CONFIRM, DATA_TYPE_DISCONNECT,DATA_TYPE_MESSAGE,DATA_TYPE_ERROR + DATA_TYPE_CONNECT, DATA_TYPE_CONFIRM, DATA_TYPE_DISCONNECT, DATA_TYPE_MESSAGE, DATA_TYPE_ERROR } /** @@ -88,7 +88,7 @@ public abstract class ConnectionHandler { protected void sendData(String sender, String receiver, DATA_TYPE type, String payload) { if (connection.isAvailable()) { try { - connection.send(new Message(type,sender,receiver,payload)); + connection.send(new Message(type, sender, receiver, payload)); } catch (SocketException e) { System.err.println("Connection closed: " + e.getMessage()); } catch (EOFException e) { diff --git a/protocol/src/main/java/ch/zhaw/pm2/multichat/protocol/Message.java b/protocol/src/main/java/ch/zhaw/pm2/multichat/protocol/Message.java index 9509b0f..b4837d3 100644 --- a/protocol/src/main/java/ch/zhaw/pm2/multichat/protocol/Message.java +++ b/protocol/src/main/java/ch/zhaw/pm2/multichat/protocol/Message.java @@ -7,7 +7,7 @@ import java.io.Serializable; */ public class Message implements Serializable { private final ConnectionHandler.DATA_TYPE type; - private String sender; + private final String sender; private final String receiver; private final String text; 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 be26302..a367fc4 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 @@ -85,7 +85,7 @@ public class Server { private void start() { System.out.println("Server started."); try { - while (true) { + while (networkServer.isAvailable()) { NetworkHandler.NetworkConnection connection = networkServer.waitForConnection(); ServerConnectionHandler connectionHandler = new ServerConnectionHandler(connection, connections); new Thread(connectionHandler).start(); 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 0dc8aee..47924ee 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 @@ -62,10 +62,8 @@ public class ServerConnectionHandler extends ConnectionHandler implements Runnab /** * Constructor to initialize the connection * - * @param connection representing the socket connection between server and client - * @param registry map containing all active connections between server and clients - - + * @param connection representing the socket connection between server and client + * @param registry map containing all active connections between server and clients */ public ServerConnectionHandler(NetworkHandler.NetworkConnection connection, Map registry) {