ClientListener + ClientConsole

This commit is contained in:
2025-03-01 12:41:40 +01:00
parent a041193ce2
commit 07ad2ba05e
7 changed files with 203 additions and 133 deletions

View File

@@ -1,23 +1,21 @@
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.util.Scanner;
import client.Client; import client.ClientConsole;
import server.Server; import server.Server;
public class ChatApp { public class ChatApp {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
Server server = new Server(6665); Server server = new Server(6665);
Client client = new Client(new InetSocketAddress("localhost", 6665)); ClientConsole client = new ClientConsole(new InetSocketAddress("localhost", 6665));
client.SendCreateRoom("101"); client.getClientInterface().SendCreateRoom("101");
Scanner scanner = new Scanner(System.in); client.joinThread();
while (true) {
String message = scanner.nextLine(); System.out.println("Stopping server ...");
System.out.print("\033[1A");
System.out.print("\r\033[2K"); server.close();
System.out.flush();
client.visitMessage(message); System.out.println("Done !");
}
} }
} }

View File

@@ -1,118 +1,54 @@
package client; package client;
import java.io.IOException;
import java.net.DatagramSocket; import java.net.DatagramSocket;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.SocketException; import java.net.SocketException;
import java.util.Objects;
import java.util.Scanner;
import network.protocol.packets.*; import network.protocol.packets.CreateRoomPacket;
import network.protocol.packets.JoinRoomPacket;
import network.protocol.packets.LeaveRoomPacket;
import network.protocol.packets.LoginPacket;
import network.protocol.packets.RequestRoomListPacket;
import network.protocol.packets.SendChatMessagePacket;
public class Client { public class Client {
private final ClientConnexion connexion; private final ClientConnexion connexion;
private final ClientListener callback;
public static void main(String[] args) { public Client(InetSocketAddress serverAddress, ClientListener callback, String pseudo) throws SocketException {
String host = "localhost"; this.connexion = new ClientConnexion(new DatagramSocket(), serverAddress, callback);
int port = 6665; this.callback = callback;
try {
Client client = new Client(new InetSocketAddress(host, port));
Scanner scanner = new Scanner(System.in);
while(true) {
String message = scanner.nextLine();
client.visitMessage(message);
}
} catch (SocketException e) {
e.printStackTrace();
}
}
public Client(InetSocketAddress serverAddress) throws SocketException {
this.connexion = new ClientConnexion(new DatagramSocket(), serverAddress);
Scanner scanner = new Scanner(System.in);
System.out.println("Enter your pseudo:");
String pseudo = scanner.nextLine();
login(pseudo); login(pseudo);
} }
public void visitMessage(String message){ public void close() {
try { //TODO: send disconnect packet
if(message.startsWith("/")){ this.connexion.close();
if(message.startsWith("/createRoom")) { this.callback.handleDisconnect();
String roomName = message.substring(12).trim();
SendCreateRoom(roomName);
} else if(message.startsWith("/listRooms")) {
RequestRoomList();
} else if(message.startsWith("/joinRoom")) {
String roomName = message.substring(10).trim();
SendJoinRoom(roomName);
} else if(message.startsWith("/leaveRoom")) {
SendLeaveRoom();
} else if(message.startsWith("/help")) {
System.out.println("Available commands:");
System.out.println("\t/createRoom <roomName>");
System.out.println("\t/listRooms");
System.out.println("\t/joinRoom <roomName>");
System.out.println("\t/leaveRoom");
System.out.println("\t/help");
}
else {
System.out.println("Unknown command");
}
} else {
SendChatMessage(message);
}
} catch (Exception e) {
e.printStackTrace();
}
} }
private void login(String pseudo) { private void login(String pseudo) {
try { this.connexion.sendPacket(new LoginPacket(pseudo));
this.connexion.sendPacket(new LoginPacket(pseudo));
} catch (IOException e) {
e.printStackTrace();
}
} }
public void SendChatMessage(String message) { public void SendChatMessage(String message) {
try { this.connexion.sendPacket(new SendChatMessagePacket(message));
this.connexion.sendPacket(new SendChatMessagePacket(message));
} catch (IOException e) {
e.printStackTrace();
}
} }
public void SendCreateRoom(String roomName) { public void SendCreateRoom(String roomName) {
try { this.connexion.sendPacket(new CreateRoomPacket(roomName));
this.connexion.sendPacket(new CreateRoomPacket(roomName));
} catch (Exception e) {
e.printStackTrace();
}
} }
public void SendJoinRoom(String roomName) { public void SendJoinRoom(String roomName) {
try { this.connexion.sendPacket(new JoinRoomPacket(roomName));
this.connexion.sendPacket(new JoinRoomPacket(roomName));
} catch (Exception e) {
e.printStackTrace();
}
} }
public void SendLeaveRoom() { public void SendLeaveRoom() {
try { this.connexion.sendPacket(new LeaveRoomPacket());
this.connexion.sendPacket(new LeaveRoomPacket());
} catch (Exception e) {
e.printStackTrace();
}
} }
public void RequestRoomList() { public void RequestRoomList() {
try { this.connexion.sendPacket(new RequestRoomListPacket());
this.connexion.sendPacket(new RequestRoomListPacket());
} catch (Exception e) {
e.printStackTrace();
}
} }
} }

View File

@@ -7,7 +7,6 @@ import java.net.InetSocketAddress;
import network.PacketHandler; import network.PacketHandler;
import network.SocketReader; import network.SocketReader;
import network.SocketWriter; import network.SocketWriter;
import network.protocol.ANSIColor;
import network.protocol.Packet; import network.protocol.Packet;
import network.protocol.PacketVisitor; import network.protocol.PacketVisitor;
import network.protocol.packets.ChatMessagePacket; import network.protocol.packets.ChatMessagePacket;
@@ -25,19 +24,27 @@ public class ClientConnexion implements PacketVisitor, PacketHandler{
private final InetSocketAddress serverAddress; private final InetSocketAddress serverAddress;
private final SocketWriter writer; private final SocketWriter writer;
private final SocketReader reader; private final SocketReader reader;
private final ClientListener callback;
public ClientConnexion(DatagramSocket socket, InetSocketAddress serverAddress) { public ClientConnexion(DatagramSocket socket, InetSocketAddress serverAddress, ClientListener callback) {
this.serverAddress = serverAddress; this.serverAddress = serverAddress;
this.writer = new SocketWriter(socket); this.writer = new SocketWriter(socket);
this.reader = new SocketReader(socket, this); this.reader = new SocketReader(socket, this);
this.callback = callback;
} }
public void close() { public void close() {
this.reader.stop(); this.reader.stop();
} }
public void sendPacket(Packet packet) throws IOException { public void sendPacket(Packet packet) {
this.writer.sendPacket(packet, serverAddress); try {
this.writer.sendPacket(packet, serverAddress);
} catch (IOException e) {
this.close();
this.callback.handleDisconnect();
e.printStackTrace();
}
} }
@Override @Override
@@ -48,16 +55,17 @@ public class ClientConnexion implements PacketVisitor, PacketHandler{
@Override @Override
public void visitPacket(ChatMessagePacket packet) { public void visitPacket(ChatMessagePacket packet) {
StringBuilder sb = new StringBuilder(); this.callback.handleChatMessage(packet.getTime(), packet.getChatter(), packet.getContent());
String time = packet.getTime().toString(); }
sb.append("&y[");
sb.append(time, 11, 19); // We only take the HH:MM:SS part @Override
sb.append("]&n"); public void visitPacket(RoomListPacket packet) {
sb.append(" "); this.callback.handleRoomList(packet.getRoomNames());
sb.append(packet.getChatter()); }
sb.append(" : ");
sb.append(packet.getContent()).append("&n"); // make the color back to normal at the end of every message @Override
System.out.println(ANSIColor.formatString(sb.toString())); public void visitPacket(ServerResponsePacket packet) {
this.callback.handleServerResponse(packet.getResponse());
} }
@Override @Override
@@ -85,25 +93,9 @@ public class ClientConnexion implements PacketVisitor, PacketHandler{
throw new UnsupportedOperationException("Unimplemented method 'visitPacket'"); throw new UnsupportedOperationException("Unimplemented method 'visitPacket'");
} }
@Override
public void visitPacket(RoomListPacket packet) {
System.out.println("Rooms :");
for (String room : packet.getRoomNames()) {
System.out.println("\t" + room);
}
}
@Override @Override
public void visitPacket(SendChatMessagePacket packet) { public void visitPacket(SendChatMessagePacket packet) {
throw new UnsupportedOperationException("Unimplemented method 'visitPacket'"); throw new UnsupportedOperationException("Unimplemented method 'visitPacket'");
} }
@Override
public void visitPacket(ServerResponsePacket packet) {
if(packet.getResponse() == ServerResponsePacket.Response.MessageSent || packet.getResponse() == ServerResponsePacket.Response.MessageNotSent) {
return;
}
System.out.println(packet.getResponse());
}
} }

View File

@@ -0,0 +1,128 @@
package client;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.time.Instant;
import java.util.List;
import java.util.Scanner;
import network.protocol.ANSIColor;
import network.protocol.packets.ServerResponsePacket;
import network.protocol.packets.ServerResponsePacket.Response;
public class ClientConsole implements ClientListener {
private Client client;
private final Thread inputThread;
private final Scanner scanner;
public static void main(String[] args) {
new ClientConsole(new InetSocketAddress("localhost", 6665));
}
public ClientConsole(InetSocketAddress address) {
this.inputThread = new Thread(this::inputLoop);
this.scanner = new Scanner(System.in);
String pseudo = inputPseudo();
try {
this.client = new Client(address, this, pseudo);
this.inputThread.start();
} catch (SocketException e) {
e.printStackTrace();
}
}
private String inputPseudo() {
System.out.println("Enter your pseudo:");
String pseudo = this.scanner.nextLine();
return pseudo;
}
public Client getClientInterface() {
return this.client;
}
private void inputLoop() {
while (!Thread.interrupted()) {
String message = scanner.nextLine();
visitMessage(message);
}
this.scanner.close();
}
public void joinThread() throws InterruptedException {
this.inputThread.join();
}
private void visitMessage(String message) {
try {
if (message.startsWith("/")) {
if (message.startsWith("/createRoom")) {
String roomName = message.substring(12).trim();
this.client.SendCreateRoom(roomName);
} else if (message.startsWith("/listRooms")) {
this.client.RequestRoomList();
} else if (message.startsWith("/joinRoom")) {
String roomName = message.substring(10).trim();
this.client.SendJoinRoom(roomName);
} else if (message.startsWith("/leaveRoom")) {
this.client.SendLeaveRoom();
} else if (message.startsWith("/bye")) {
this.client.close();
} else if (message.startsWith("/help")) {
System.out.println("Available commands:");
System.out.println("\t/bye");
System.out.println("\t/createRoom <roomName>");
System.out.println("\t/listRooms");
System.out.println("\t/joinRoom <roomName>");
System.out.println("\t/leaveRoom");
System.out.println("\t/help");
} else {
System.out.println("Unknown command");
}
} else {
this.client.SendChatMessage(message);
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void handleDisconnect() {
System.out.println("Disconnected !");
this.inputThread.interrupt();
}
@Override
public void handleChatMessage(Instant time, String chatter, String content) {
StringBuilder sb = new StringBuilder();
String strTime = time.toString();
sb.append("&y[");
sb.append(strTime, 11, 19); // We only take the HH:MM:SS part
sb.append("]&n");
sb.append(" ");
sb.append(chatter);
sb.append(" : ");
sb.append(content).append("&n"); // make the color back to normal at the end of every message
System.out.println(ANSIColor.formatString(sb.toString()));
}
@Override
public void handleRoomList(List<String> roomNames) {
System.out.println("Rooms :");
for (String room : roomNames) {
System.out.println("\t" + room);
}
}
@Override
public void handleServerResponse(Response response) {
if (response == ServerResponsePacket.Response.MessageSent
|| response == ServerResponsePacket.Response.MessageNotSent) {
return;
}
System.out.println(response);
}
}

View File

@@ -0,0 +1,15 @@
package client;
import java.time.Instant;
import java.util.List;
import network.protocol.packets.ServerResponsePacket;
public interface ClientListener {
void handleDisconnect();
void handleChatMessage(Instant time, String chatter, String content);
void handleRoomList(List<String> roomNames);
void handleServerResponse(ServerResponsePacket.Response response);
}

View File

@@ -24,6 +24,7 @@ public class SocketReader {
public void stop() { public void stop() {
this.readThread.interrupt(); this.readThread.interrupt();
socket.close();
} }
private void readLoop() { private void readLoop() {

View File

@@ -1,19 +1,19 @@
package network.protocol.packets; package network.protocol.packets;
import java.util.ArrayList; import java.util.List;
import network.protocol.Packet; import network.protocol.Packet;
import network.protocol.PacketVisitor; import network.protocol.PacketVisitor;
public class RoomListPacket extends Packet { public class RoomListPacket extends Packet {
private final ArrayList<String> roomNames; private final List<String> roomNames;
public RoomListPacket(ArrayList<String> roomNames) { public RoomListPacket(List<String> roomNames) {
this.roomNames = roomNames; this.roomNames = roomNames;
} }
public ArrayList<String> getRoomNames() { public List<String> getRoomNames() {
return roomNames; return roomNames;
} }