diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/chat/Message.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/chat/Message.java new file mode 100644 index 0000000..44e2c45 --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/chat/Message.java @@ -0,0 +1,57 @@ +package ch.unibas.dmi.dbis.cs108.casono.client.chat; + +import java.time.LocalTime; + +public class Message { + private String message; + public String name; + public int hourTime; + public int minuteTime; + public int game_id = 0; + public String target = null; + + // For Global Chat + + public Message(String message, String name) { + this.message = message; + this.name = name; + LocalTime now = LocalTime.now(); + this.hourTime = now.getHour(); + this.minuteTime = now.getMinute(); + } + + // For Lobby Chat + + public Message(String message, String name, int game_id) { + this.message = message; + this.name = name; + LocalTime now = LocalTime.now(); + this.hourTime = now.getHour(); + this.minuteTime = now.getMinute(); + this.game_id = game_id; + } + + // For Whisper Chat + + public Message(String message, String name, int game_id, String target) { + this.message = message; + this.name = name; + LocalTime now = LocalTime.now(); + this.hourTime = now.getHour(); + this.minuteTime = now.getMinute(); + this.game_id = game_id; + this.target = target; + } + + public String getMessage() { + return message; + } + + public String toString() { + return String.format("%s: %s", this.name, this.message); + } + + public void print() { + System.out.println(this.toString()); + } +} diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/network/ClientService.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/network/ClientService.java new file mode 100644 index 0000000..e8f9f28 --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/network/ClientService.java @@ -0,0 +1,110 @@ +package ch.unibas.dmi.dbis.cs108.casono.client.network; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.net.Socket; +import java.util.ArrayList; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +import java.io.IOException; +import java.net.UnknownHostException; + +import ch.unibas.dmi.dbis.cs108.casono.client.chat.Message; + +/** + * Responsible for the transferring of the data from the Client to the Server and the other way around + */ + +public class ClientService { + + private Socket socket; + private BufferedReader input; + private BufferedWriter output; + + private String ip; + private int port; + + private ExecutorService executor; + + /** + * Creates a new ClientSession with a Socket, a Reader and Writer of the Input- and the Outputstream and a pool of threads to send requests and receive responses. + * @param ip : ip-adress of the server + * @param port : port of the server + */ + + public ClientService(String ip, int port) { + + this.ip = ip; + this.port = port; + + try { + socket = new Socket(this.ip, this.port); + System.out.println("Connected"); + input = new BufferedReader(new InputStreamReader(socket.getInputStream())); + output = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); + } + catch (UnknownHostException u) { + System.out.println(u); + return; + } + catch (IOException i) { + System.out.println(i); + return; + } + + executor = Executors.newSingleThreadExecutor(); + + + } + + /** + * Sends a Chat Message to the Server and awaits a response, which will be passed along + * @param message : Protocol Message of type "Message" to be sent to the server + * @return ArrayList : The Response of the Server to be interpreted later + */ + + public Future> sendMessage(Message message) { + + String time = message.hourTime + ":" + message.minuteTime; + + String request = ""; + + if (message.target == null && message.game_id == 0) { + request = String.format("SEND_MESSAGE TYPE=GLOBAL GAME=null USER=%s TARGET=null TEXT=%s TIME=%s", message.name, message.getMessage(), time); + } + else if (message.target == null) { + request = String.format("SEND_MESSAGE TYPE=LOBBY GAME=%d USER=%s TARGET=null TEXT=%s TIME=%s", message.game_id, message.name, message.getMessage(), time); + } else { + request = String.format("SEND_MESSAGE TYPE=WHISPER GAME=%d USER=%s TARGET=%s TEXT=%s TIME=%s", message.game_id, message.name, message.target, message.getMessage(), time); + } + + System.out.println("Writing following request: " + request); + + sendRequest task = new sendRequest(request, input, output); + + Future> response = executor.submit(task); + + return response; + } + + /** + * Closes the Socket and shuts down the Threadpool associated with that Socket-Connection. + */ + + public void closeSocket() { + + try { + executor.shutdown(); + input.close(); + output.close(); + socket.close(); + } catch (IOException j) { + System.out.println(j); + } + + } +} diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/network/sendRequest.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/network/sendRequest.java new file mode 100644 index 0000000..cb0a4fb --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/client/network/sendRequest.java @@ -0,0 +1,49 @@ +package ch.unibas.dmi.dbis.cs108.casono.client.network; + +import java.io.BufferedReader; +import java.util.concurrent.Callable; + +import java.util.ArrayList; + +import java.io.*; + +public class sendRequest implements Callable> { + + final private String request; + final private BufferedReader input; + final private BufferedWriter output; + + public sendRequest(String request, BufferedReader input, BufferedWriter output) { + this.request = request; + this.input = input; + this.output = output; + } + + @Override + public ArrayList call() throws Exception { + try { + output.write(request+"\n"); + output.flush(); + System.out.println("Writing following request: " + request); + } catch (Exception e) { + System.out.println(e); + } + + ArrayList response = new ArrayList<>(); + + try { + String line; + while ((line = input.readLine()) != null) { + if (line.toLowerCase().startsWith("ok")) { + break; + } + response.add(line); + } + + System.out.println("Response from server: " + response.get(0)); + } + catch (Exception e) {System.out.println(e);} + + return response; + } +} diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/Server.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/Server.java new file mode 100644 index 0000000..98bbbcc --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/Server.java @@ -0,0 +1,59 @@ +package ch.unibas.dmi.dbis.cs108.casono.server; + +import java.io.*; +import java.net.ServerSocket; +import java.net.Socket; + +public class Server { + private ServerSocket ss = null; + private BufferedReader input = null; + private BufferedWriter output = null; + + public Server(int port) { + try { + ss = new ServerSocket(port); + System.out.println("Server started"); + } + catch (IOException e) { + System.out.println(e.getMessage()); + } + } + + public void simpleListenLoop() { + System.out.println("Waiting for connection..."); + Socket s = null; + try { + while (true) { + s = ss.accept(); + System.out.println("Accepted connection"); + + input = new BufferedReader(new InputStreamReader(s.getInputStream())); + + output = new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); + String line = null; + while((line = input.readLine())!=null) { + System.out.println("Server got "+ line); + // do something with this line + output.write("OK"+"\n"); + output.flush(); + if(Thread.currentThread().isInterrupted()) { + return; + } + } + if(Thread.currentThread().isInterrupted()) { + return; + } + } + } catch (IOException e) { + throw new RuntimeException(e); + } finally { + try { + s.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + } + +} \ No newline at end of file diff --git a/src/test/java/ch/unibas/dmi/dbis/cs108/casono/client/network/ClientServiceTest.java b/src/test/java/ch/unibas/dmi/dbis/cs108/casono/client/network/ClientServiceTest.java new file mode 100644 index 0000000..56cc2d5 --- /dev/null +++ b/src/test/java/ch/unibas/dmi/dbis/cs108/casono/client/network/ClientServiceTest.java @@ -0,0 +1,35 @@ +package ch.unibas.dmi.dbis.cs108.casono.client.network; + +import ch.unibas.dmi.dbis.cs108.casono.client.chat.Message; +import ch.unibas.dmi.dbis.cs108.casono.server.Server; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +public class ClientServiceTest { + + Server server = null; + private Thread serverThread; + + @BeforeEach + public void setUp() { + server = new Server(5000); + serverThread = new Thread(()-> server.simpleListenLoop()); + serverThread.start(); + } + @AfterEach + public void tearDown() { + serverThread.interrupt(); + } + @Test + public void testClientService() throws ExecutionException, InterruptedException { + ClientService client = new ClientService("localhost", 5000); + Future> future = client.sendMessage(new Message("bla", "name")); + future.get(); + client.closeSocket(); + } +}