Compare commits
3 Commits
handshake
...
0533c16cf2
| Author | SHA1 | Date | |
|---|---|---|---|
| 0533c16cf2 | |||
| 63ec7b3aaa | |||
| 07ad2ba05e |
@@ -30,10 +30,3 @@ You will also be able to create a new room.
|
|||||||
- /joinRoom *roomName*
|
- /joinRoom *roomName*
|
||||||
- /leaveRoom
|
- /leaveRoom
|
||||||
- /help
|
- /help
|
||||||
|
|
||||||
> [!NOTE]
|
|
||||||
> There are some aliases for the commands:
|
|
||||||
> - /create
|
|
||||||
> - /list
|
|
||||||
> - /join
|
|
||||||
> - /leave
|
|
||||||
@@ -1,24 +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 {
|
||||||
int port = 6665;
|
Server server = new Server(6665);
|
||||||
Server server = new Server(port);
|
ClientConsole client = new ClientConsole(new InetSocketAddress("localhost", 6665));
|
||||||
Client client = new Client(new InetSocketAddress("localhost", port));
|
|
||||||
|
|
||||||
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 !");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,142 +1,55 @@
|
|||||||
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.ANSIColor;
|
import network.protocol.packets.CreateRoomPacket;
|
||||||
import network.protocol.packets.*;
|
import network.protocol.packets.DisconnectPacket;
|
||||||
|
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);
|
|
||||||
int tries = 0;
|
|
||||||
try {
|
|
||||||
connexion.sendPacket(new HandshakePacket());
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
while(!connexion.connected) {
|
|
||||||
try {
|
|
||||||
Thread.sleep(100);
|
|
||||||
if(tries++ > 5) {
|
|
||||||
System.out.println("Server is not responding");
|
|
||||||
System.exit(1);
|
|
||||||
}
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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 {
|
this.connexion.sendPacket(new DisconnectPacket("Leaving"));
|
||||||
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("/create ")){
|
|
||||||
String roomName = message.substring(8).trim();
|
|
||||||
SendCreateRoom(roomName);
|
|
||||||
} else if(message.equals("/listRooms") || message.equals("/list")) {
|
|
||||||
RequestRoomList();
|
|
||||||
} else if(message.startsWith("/joinRoom ")) {
|
|
||||||
String roomName = message.substring(10).trim();
|
|
||||||
SendJoinRoom(roomName);
|
|
||||||
} else if(message.startsWith("/join ")){
|
|
||||||
String roomName = message.substring(6).trim();
|
|
||||||
SendJoinRoom(roomName);
|
|
||||||
} else if(message.equals("/leaveRoom") || message.equals("/leave")) {
|
|
||||||
SendLeaveRoom();
|
|
||||||
} else if(message.equals("/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(ANSIColor.formatString("&rUnknown command&n"));
|
|
||||||
}
|
|
||||||
} 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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,30 +7,45 @@ 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.*;
|
import network.protocol.packets.ChatMessagePacket;
|
||||||
|
import network.protocol.packets.CreateRoomPacket;
|
||||||
|
import network.protocol.packets.DisconnectPacket;
|
||||||
|
import network.protocol.packets.JoinRoomPacket;
|
||||||
|
import network.protocol.packets.LeaveRoomPacket;
|
||||||
|
import network.protocol.packets.LoginPacket;
|
||||||
|
import network.protocol.packets.RequestRoomListPacket;
|
||||||
|
import network.protocol.packets.RoomListPacket;
|
||||||
|
import network.protocol.packets.SendChatMessagePacket;
|
||||||
|
import network.protocol.packets.ServerResponsePacket;
|
||||||
|
|
||||||
public class ClientConnexion implements PacketVisitor, PacketHandler{
|
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;
|
||||||
protected boolean connected = false;
|
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) {
|
||||||
|
try {
|
||||||
this.writer.sendPacket(packet, serverAddress);
|
this.writer.sendPacket(packet, serverAddress);
|
||||||
|
} catch (IOException e) {
|
||||||
|
this.close();
|
||||||
|
this.callback.handleDisconnect();
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -41,16 +56,23 @@ 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[")
|
|
||||||
.append(time, 11, 19) // We only take the HH:MM:SS part
|
@Override
|
||||||
.append("]&n")
|
public void visitPacket(RoomListPacket packet) {
|
||||||
.append(" ")
|
this.callback.handleRoomList(packet.getRoomNames());
|
||||||
.append(packet.getChatter())
|
}
|
||||||
.append(" : ")
|
|
||||||
.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
|
||||||
|
public void visitPacket(DisconnectPacket packet) {
|
||||||
|
this.close();
|
||||||
|
this.callback.handleDisconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -78,29 +100,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());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitPacket(HandshakePacket packet) {
|
|
||||||
connected = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
128
ChatApp/src/client/ClientConsole.java
Normal file
128
ChatApp/src/client/ClientConsole.java
Normal 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
15
ChatApp/src/client/ClientListener.java
Normal file
15
ChatApp/src/client/ClientListener.java
Normal 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);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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() {
|
||||||
|
|||||||
@@ -1,6 +1,15 @@
|
|||||||
package network.protocol;
|
package network.protocol;
|
||||||
|
|
||||||
import network.protocol.packets.*;
|
import network.protocol.packets.ChatMessagePacket;
|
||||||
|
import network.protocol.packets.CreateRoomPacket;
|
||||||
|
import network.protocol.packets.DisconnectPacket;
|
||||||
|
import network.protocol.packets.JoinRoomPacket;
|
||||||
|
import network.protocol.packets.LeaveRoomPacket;
|
||||||
|
import network.protocol.packets.LoginPacket;
|
||||||
|
import network.protocol.packets.RequestRoomListPacket;
|
||||||
|
import network.protocol.packets.RoomListPacket;
|
||||||
|
import network.protocol.packets.SendChatMessagePacket;
|
||||||
|
import network.protocol.packets.ServerResponsePacket;
|
||||||
|
|
||||||
public interface PacketVisitor {
|
public interface PacketVisitor {
|
||||||
|
|
||||||
@@ -10,6 +19,7 @@ public interface PacketVisitor {
|
|||||||
|
|
||||||
void visitPacket(ChatMessagePacket packet);
|
void visitPacket(ChatMessagePacket packet);
|
||||||
void visitPacket(CreateRoomPacket packet);
|
void visitPacket(CreateRoomPacket packet);
|
||||||
|
void visitPacket(DisconnectPacket packet);
|
||||||
void visitPacket(JoinRoomPacket packet);
|
void visitPacket(JoinRoomPacket packet);
|
||||||
void visitPacket(LeaveRoomPacket packet);
|
void visitPacket(LeaveRoomPacket packet);
|
||||||
void visitPacket(LoginPacket packet);
|
void visitPacket(LoginPacket packet);
|
||||||
@@ -17,5 +27,5 @@ public interface PacketVisitor {
|
|||||||
void visitPacket(RoomListPacket packet);
|
void visitPacket(RoomListPacket packet);
|
||||||
void visitPacket(SendChatMessagePacket packet);
|
void visitPacket(SendChatMessagePacket packet);
|
||||||
void visitPacket(ServerResponsePacket packet);
|
void visitPacket(ServerResponsePacket packet);
|
||||||
void visitPacket(HandshakePacket packet);
|
|
||||||
}
|
}
|
||||||
|
|||||||
23
ChatApp/src/network/protocol/packets/DisconnectPacket.java
Normal file
23
ChatApp/src/network/protocol/packets/DisconnectPacket.java
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
package network.protocol.packets;
|
||||||
|
|
||||||
|
import network.protocol.Packet;
|
||||||
|
import network.protocol.PacketVisitor;
|
||||||
|
|
||||||
|
public class DisconnectPacket extends Packet {
|
||||||
|
|
||||||
|
private final String reason;
|
||||||
|
|
||||||
|
public DisconnectPacket(String reason) {
|
||||||
|
this.reason = reason;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getReason() {
|
||||||
|
return reason;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(PacketVisitor packetVisitor) {
|
||||||
|
packetVisitor.visitPacket(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
package network.protocol.packets;
|
|
||||||
|
|
||||||
import network.protocol.Packet;
|
|
||||||
import network.protocol.PacketVisitor;
|
|
||||||
|
|
||||||
public class HandshakePacket extends Packet {
|
|
||||||
public HandshakePacket() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void accept(PacketVisitor packetVisitor) {
|
|
||||||
packetVisitor.visitPacket(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,21 +19,21 @@ public class Server implements PacketHandler {
|
|||||||
private final DatagramSocket serverSocket;
|
private final DatagramSocket serverSocket;
|
||||||
private final Map<InetSocketAddress, ServerConnexion> connexions;
|
private final Map<InetSocketAddress, ServerConnexion> connexions;
|
||||||
private final SocketReader reader;
|
private final SocketReader reader;
|
||||||
private final Map<String, ArrayList<ServerConnexion>> roomNames;
|
private final Map<String, ArrayList<ServerConnexion>> rooms;
|
||||||
|
|
||||||
public Server(int port) throws SocketException {
|
public Server(int port) throws SocketException {
|
||||||
this.serverSocket = new DatagramSocket(port);
|
this.serverSocket = new DatagramSocket(port);
|
||||||
this.connexions = new HashMap<>();
|
this.connexions = new HashMap<>();
|
||||||
this.reader = new SocketReader(serverSocket, this);
|
this.reader = new SocketReader(serverSocket, this);
|
||||||
this.roomNames = new HashMap<>();
|
this.rooms = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrayList<String> getRoomNames() {
|
public ArrayList<String> getRoomNames() {
|
||||||
return roomNames.keySet().stream().collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
|
return rooms.keySet().stream().collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getRoomName(ServerConnexion connexion) {
|
public String getRoomName(ServerConnexion connexion) {
|
||||||
for (Map.Entry<String, ArrayList<ServerConnexion>> entry : roomNames.entrySet()) {
|
for (Map.Entry<String, ArrayList<ServerConnexion>> entry : rooms.entrySet()) {
|
||||||
if (entry.getValue().contains(connexion)) {
|
if (entry.getValue().contains(connexion)) {
|
||||||
return entry.getKey();
|
return entry.getKey();
|
||||||
}
|
}
|
||||||
@@ -41,43 +41,45 @@ public class Server implements PacketHandler {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void createRoom(String roomName, ServerConnexion connexion) throws SocketException {
|
public boolean createRoom(String roomName, ServerConnexion connexion) {
|
||||||
if(roomNames.containsKey(roomName)) {
|
if (rooms.containsKey(roomName)) {
|
||||||
throw new SocketException("Room already exists");
|
return false;
|
||||||
}
|
}
|
||||||
roomNames.put(roomName, new ArrayList<>());
|
rooms.put(roomName, new ArrayList<>());
|
||||||
roomNames.get(roomName).add(connexion);
|
rooms.get(roomName).add(connexion);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void leaveRoom(ServerConnexion connexion) throws SocketException {
|
public boolean leaveRoom(ServerConnexion connexion) {
|
||||||
String roomName = getRoomName(connexion);
|
String roomName = getRoomName(connexion);
|
||||||
if (roomName != null) {
|
if (roomName != null) {
|
||||||
roomNames.get(roomName).remove(connexion);
|
rooms.get(roomName).remove(connexion);
|
||||||
// Remove the room if it is empty
|
// Remove the room if it is empty
|
||||||
if(roomNames.get(roomName).isEmpty()) {
|
if (rooms.get(roomName).isEmpty()) {
|
||||||
roomNames.remove(roomName);
|
rooms.remove(roomName);
|
||||||
}
|
}
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
throw new SocketException("Room does not exist");
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void joinRoom(String roomName, ServerConnexion connexion) throws SocketException {
|
public boolean joinRoom(String roomName, ServerConnexion connexion) {
|
||||||
if(roomNames.containsKey(roomName) && !roomNames.get(roomName).contains(connexion)) {
|
if (rooms.containsKey(roomName) && !rooms.get(roomName).contains(connexion)) {
|
||||||
roomNames.get(roomName).add(connexion);
|
rooms.get(roomName).add(connexion);
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
throw new SocketException("Room does not exist");
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendToRoom(ServerConnexion connexion, SendChatMessagePacket packet) throws SocketException {
|
public boolean sendToRoom(ServerConnexion connexion, SendChatMessagePacket packet) {
|
||||||
String roomName = getRoomName(connexion);
|
String roomName = getRoomName(connexion);
|
||||||
ChatMessagePacket chatPacket = new ChatMessagePacket(Instant.now(), connexion.getChatterName(), packet.getContent());
|
ChatMessagePacket chatPacket = new ChatMessagePacket(Instant.now(), connexion.getChatterName(),
|
||||||
if(roomName != null && roomNames.containsKey(roomName)) {
|
packet.getContent());
|
||||||
roomNames.get(roomName).forEach(con -> con.sendPacket(chatPacket));
|
if (roomName != null && rooms.containsKey(roomName)) {
|
||||||
return;
|
rooms.get(roomName).forEach(con -> con.sendPacket(chatPacket));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
throw new SocketException("You are not in a room or the room does not exist");
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void close() {
|
public void close() {
|
||||||
@@ -89,6 +91,20 @@ public class Server implements PacketHandler {
|
|||||||
.anyMatch(connexion -> pseudo.equals(connexion.getChatterName()));
|
.anyMatch(connexion -> pseudo.equals(connexion.getChatterName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void removeConnexion(ServerConnexion connexion) {
|
||||||
|
for (var it = this.connexions.entrySet().iterator(); it.hasNext();) {
|
||||||
|
var entry = it.next();
|
||||||
|
if (entry.getValue() == connexion) {
|
||||||
|
it.remove();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (var entry : this.rooms.entrySet()) {
|
||||||
|
if (entry.getValue().remove(connexion))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handlePacket(Packet packet, InetSocketAddress address) {
|
public void handlePacket(Packet packet, InetSocketAddress address) {
|
||||||
if (!connexions.containsKey(address)) {
|
if (!connexions.containsKey(address)) {
|
||||||
|
|||||||
@@ -3,12 +3,20 @@ package server;
|
|||||||
import java.io.IOException;
|
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 network.SocketWriter;
|
import network.SocketWriter;
|
||||||
import network.protocol.Packet;
|
import network.protocol.Packet;
|
||||||
import network.protocol.PacketVisitor;
|
import network.protocol.PacketVisitor;
|
||||||
import network.protocol.packets.*;
|
import network.protocol.packets.ChatMessagePacket;
|
||||||
|
import network.protocol.packets.CreateRoomPacket;
|
||||||
|
import network.protocol.packets.DisconnectPacket;
|
||||||
|
import network.protocol.packets.JoinRoomPacket;
|
||||||
|
import network.protocol.packets.LeaveRoomPacket;
|
||||||
|
import network.protocol.packets.LoginPacket;
|
||||||
|
import network.protocol.packets.RequestRoomListPacket;
|
||||||
|
import network.protocol.packets.RoomListPacket;
|
||||||
|
import network.protocol.packets.SendChatMessagePacket;
|
||||||
|
import network.protocol.packets.ServerResponsePacket;
|
||||||
import network.protocol.packets.ServerResponsePacket.Response;
|
import network.protocol.packets.ServerResponsePacket.Response;
|
||||||
|
|
||||||
public class ServerConnexion implements PacketVisitor {
|
public class ServerConnexion implements PacketVisitor {
|
||||||
@@ -33,43 +41,26 @@ public class ServerConnexion implements PacketVisitor {
|
|||||||
this.writer.sendPacket(packet, clientAddress);
|
this.writer.sendPacket(packet, clientAddress);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
this.server.removeConnexion(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitPacket(ChatMessagePacket packet) {
|
|
||||||
// I'm never supposed to receive this from the client
|
|
||||||
throw new UnsupportedOperationException("Unimplemented method 'visitPacket'");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitPacket(CreateRoomPacket packet) {
|
public void visitPacket(CreateRoomPacket packet) {
|
||||||
try {
|
boolean created = server.createRoom(packet.getRoomName(), this);
|
||||||
server.createRoom(packet.getRoomName(), this);
|
sendPacket(new ServerResponsePacket(created ? Response.RoomCreated : Response.RoomNotCreated));
|
||||||
sendPacket(new ServerResponsePacket(Response.RoomCreated));
|
|
||||||
} catch (SocketException e) {
|
|
||||||
sendPacket(new ServerResponsePacket(Response.RoomNotCreated));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitPacket(JoinRoomPacket packet) {
|
public void visitPacket(JoinRoomPacket packet) {
|
||||||
try {
|
boolean joined = server.joinRoom(packet.getRoomName(), this);
|
||||||
server.joinRoom(packet.getRoomName(), this);
|
sendPacket(new ServerResponsePacket(joined ? Response.RoomJoined : Response.RoomNotJoined));
|
||||||
sendPacket(new ServerResponsePacket(Response.RoomJoined));
|
|
||||||
} catch (SocketException e) {
|
|
||||||
sendPacket(new ServerResponsePacket(Response.RoomNotJoined));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitPacket(LeaveRoomPacket packet) {
|
public void visitPacket(LeaveRoomPacket packet) {
|
||||||
try {
|
boolean left = server.leaveRoom(this);
|
||||||
server.leaveRoom(this);
|
sendPacket(new ServerResponsePacket(left ? Response.RoomLeft : Response.RoomNotLeft));
|
||||||
sendPacket(new ServerResponsePacket(Response.RoomLeft));
|
|
||||||
} catch (SocketException e) {
|
|
||||||
sendPacket(new ServerResponsePacket(Response.RoomNotLeft));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -89,6 +80,22 @@ public class ServerConnexion implements PacketVisitor {
|
|||||||
sendPacket(new RoomListPacket(server.getRoomNames()));
|
sendPacket(new RoomListPacket(server.getRoomNames()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitPacket(SendChatMessagePacket packet) {
|
||||||
|
boolean messageSent = server.sendToRoom(this, packet);
|
||||||
|
sendPacket(new ServerResponsePacket(messageSent ? Response.MessageSent : Response.MessageNotSent));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitPacket(DisconnectPacket packet) {
|
||||||
|
this.onDisconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onDisconnect() {
|
||||||
|
this.server.removeConnexion(this);
|
||||||
|
System.out.println("[Server] Chatter " + chatterName + " disconnected !");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitPacket(RoomListPacket packet) {
|
public void visitPacket(RoomListPacket packet) {
|
||||||
// I'm never supposed to receive this from the client
|
// I'm never supposed to receive this from the client
|
||||||
@@ -96,12 +103,9 @@ public class ServerConnexion implements PacketVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitPacket(SendChatMessagePacket packet) {
|
public void visitPacket(ChatMessagePacket packet) {
|
||||||
try {
|
// I'm never supposed to receive this from the client
|
||||||
server.sendToRoom(this, packet);
|
throw new UnsupportedOperationException("Unimplemented method 'visitPacket'");
|
||||||
} catch (SocketException e) {
|
|
||||||
sendPacket(new ServerResponsePacket(Response.MessageNotSent));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -110,10 +114,4 @@ public class ServerConnexion implements PacketVisitor {
|
|||||||
throw new UnsupportedOperationException("Unimplemented method 'visitPacket'");
|
throw new UnsupportedOperationException("Unimplemented method 'visitPacket'");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitPacket(HandshakePacket packet) {
|
|
||||||
System.out.println("[Server] Handshake received from " + clientAddress);
|
|
||||||
sendPacket(new HandshakePacket());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user