diff --git a/src/.DS_Store b/src/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..c0351d348949e30f36702ba1488f9caa9cf045c9 Binary files /dev/null and b/src/.DS_Store differ diff --git a/src/chat/Chat.java b/src/chat/Chat.java new file mode 100644 index 0000000000000000000000000000000000000000..9342928010ed7779674312128ae753660aaf0bbb --- /dev/null +++ b/src/chat/Chat.java @@ -0,0 +1,14 @@ +package chat; + +import java.rmi.Remote; +import java.rmi.RemoteException; +import java.util.List; + +public interface Chat extends Remote { + public void sendMessage(ClientInterface client, String message) throws RemoteException; + public void saveMessageTofile( MessageList message) throws RemoteException; + public void exitChat(ClientInterface client) throws RemoteException; + void registerUsers(ClientInterface client,String username) throws RemoteException; + public void broadcasteMessages(Message message) throws RemoteException; + public MessageList loadHistory() throws RemoteException; +} \ No newline at end of file diff --git a/src/chat/ClientInterface.java b/src/chat/ClientInterface.java new file mode 100644 index 0000000000000000000000000000000000000000..96f5e02cada89d3c5244f7a7c81f83223e83139e --- /dev/null +++ b/src/chat/ClientInterface.java @@ -0,0 +1,8 @@ +package chat; + +import java.rmi.Remote; +import java.rmi.RemoteException; + +public interface ClientInterface extends Remote { + public void showMessages(String message) throws RemoteException; // Correct name +} diff --git a/src/chat/Message.java b/src/chat/Message.java new file mode 100644 index 0000000000000000000000000000000000000000..0952eb7c708fba3145be1cc91faa8476f5bcae31 --- /dev/null +++ b/src/chat/Message.java @@ -0,0 +1,27 @@ +package chat; + +import java.io.Serializable; + +public class Message implements Serializable{ + private static final long serialVersionUID = 1234567L; + String username; + String message; + + public Message(String username, String message){ + this.username=username; + this.message=message; + } + + public String getUsername(String username){ + return username; + } + + public String getMessage(String message){ + return message; + } + + public String toString(){ + return username + ": " + message; + } + +} diff --git a/src/chat/MessageList.java b/src/chat/MessageList.java new file mode 100644 index 0000000000000000000000000000000000000000..19726c54a00ce0597d31826a84e5f7cf39af8ce1 --- /dev/null +++ b/src/chat/MessageList.java @@ -0,0 +1,19 @@ +package chat; + +import java.io.Serializable; +import java.util.*; + +public class MessageList implements Serializable{ + private static final long serialVersionUID = 1234569L; + private List<Message> msgList=new ArrayList<>(); + +public List<Message> getMsgList() { + return msgList; +} + +public void setMsgList(List<Message> msgList) { + this.msgList = msgList; +} + + +} diff --git a/src/client/.DS_Store b/src/client/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..480f84bb745f46e77404ae7985030f8e816dd16e Binary files /dev/null and b/src/client/.DS_Store differ diff --git a/src/client/Client.java b/src/client/Client.java new file mode 100644 index 0000000000000000000000000000000000000000..bfc53baeab72f29355c123e55be5659d85e43975 --- /dev/null +++ b/src/client/Client.java @@ -0,0 +1,54 @@ +package client; + +import java.rmi.registry.LocateRegistry; +import java.rmi.registry.Registry; +import java.util.Scanner; + +import chat.Chat; + +public class Client { + public static void main(String [] args) { + + try { + /*if (args.length < 2) { + System.out.println("Usage: java HelloClient <rmiregistry host> <rmiregistry port>"); + return;}*/ + + //String host = args[0]; + //int port = Integer.parseInt(args[1]); + String host = "localhost"; + int port = 2099; + Registry registry = LocateRegistry.getRegistry(host, port); + Chat chat = (Chat) registry.lookup("ChatService"); + + Scanner scanner = new Scanner(System.in); + System.out.print("Enter your username: "); + String username = scanner.nextLine(); + + ClientSide client = new ClientSide(); + + // Remote method invocation + chat.registerUsers(client, username); + + System.out.println("Welcome to the chat, " + username + "! Type your messages below:"); + + while (true) { + String message = scanner.nextLine(); + + // Exit command + if (message.equalsIgnoreCase("/exit")) { + chat.exitChat(client); // Notify the server about exiting + System.out.println("You have left the chat."); + break; + } + + // Send message to the server + chat.sendMessage(client, message); + } + + } catch (Exception e) { +// System.err.println("Error on client: " + e); + e.printStackTrace(); + } + } +} diff --git a/src/client/ClientSide.java b/src/client/ClientSide.java new file mode 100644 index 0000000000000000000000000000000000000000..4df18347074188254413df41588eaf08c78b6fd1 --- /dev/null +++ b/src/client/ClientSide.java @@ -0,0 +1,20 @@ +package client; + +import java.rmi.RemoteException; +import java.rmi.server.UnicastRemoteObject; + +import chat.ClientInterface; +import chat.Message; + +public class ClientSide extends UnicastRemoteObject implements ClientInterface { + + protected ClientSide() throws RemoteException { + super(); + } + + @Override + public void showMessages(String message) { + System.out.println(message); + } +} + diff --git a/src/server/.DS_Store b/src/server/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..45b86a0275bde25ff4f06319191e434c9bfdbce8 Binary files /dev/null and b/src/server/.DS_Store differ diff --git a/src/server/ChatApp.java b/src/server/ChatApp.java new file mode 100644 index 0000000000000000000000000000000000000000..bcbe1b8128806e9068d84613346ef1d25e78b92d --- /dev/null +++ b/src/server/ChatApp.java @@ -0,0 +1,129 @@ +package server; + + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.rmi.RemoteException; +import java.util.*; +import java.util.Map.Entry; + +import chat.Chat; +import chat.ClientInterface; +import chat.Message; +import chat.MessageList; + +public class ChatApp implements Chat{ + + Map<ClientInterface, String> activeUsers = new HashMap<>(); + private List <Message> messages=new ArrayList<>(); + @Override + public void registerUsers(ClientInterface client, String username) throws RemoteException { + MessageList history=loadHistory(); + if (activeUsers.containsValue(username)) { + throw new RemoteException("Username already taken! Please choose another one."); + } else { + activeUsers.put(client,username); + if(history!=null){ + for(Message msg: history.getMsgList()){ + try{ + client.showMessages(msg.toString()); + }catch(Exception e){ + e.printStackTrace(); + } + } + } + System.out.println(username + " has joined the chat."); + } + } + + + @Override + public void sendMessage(ClientInterface client, String message) throws RemoteException { + String username = activeUsers.get(client); + + if(username==null) { + System.out.println("Please register first"); + } + + Message msg= new Message(username, message); + messages.add(msg); + saveMessage(msg); + broadcasteMessages(msg); + } + + private void saveMessage(Message msg) throws RemoteException{ + MessageList messageList= loadHistory(); + + if(messageList==null){ + System.out.println("No previous history found \n"); + MessageList messageListNew= new MessageList(); + messageListNew.getMsgList().add(msg); + saveMessageTofile(messageListNew); + + }else{ + messageList.getMsgList().add(msg); + saveMessageTofile(messageList); + + } + } + + @Override + public void exitChat(ClientInterface client) throws RemoteException { + activeUsers.remove(client); + } + + + @Override + public void broadcasteMessages(Message message) throws RemoteException { + for (Entry<ClientInterface, String> entry : activeUsers.entrySet()) { + try { + ClientInterface client = entry.getKey(); + client.showMessages(message.toString()); + }catch (RemoteException e) { + System.out.println("Error sending message to " + entry.getKey() + ": " + e.getMessage()); + } + + } + } + + @Override + public void saveMessageTofile( MessageList message) throws RemoteException { + try (FileOutputStream file= new FileOutputStream("chat_history.ser"); + ObjectOutputStream out= new ObjectOutputStream(file)){ + out.writeObject(message); + // Append message to the file + } catch (IOException e) { + System.out.println("Error saving message: " + e.getMessage()); + } + + } + + @Override +public MessageList loadHistory() throws RemoteException { + MessageList msg=null; + try (FileInputStream file = new FileInputStream("chat_history.ser"); + ObjectInputStream input = new ObjectInputStream(file)) { + + + try { + msg= (MessageList) input.readObject(); + if(msg!=null){ + for(Message message : msg.getMsgList()){ + + } + } + } catch (IOException e) { + e.printStackTrace(); + } + + + } catch (Exception e) { + } + + return msg; +} + +} diff --git a/src/server/Server.java b/src/server/Server.java new file mode 100644 index 0000000000000000000000000000000000000000..23200fd26c410c9588c1febaa69cd719817dd869 --- /dev/null +++ b/src/server/Server.java @@ -0,0 +1,33 @@ +package server; + +import java.rmi.registry.LocateRegistry; +import java.rmi.registry.Registry; +import java.rmi.server.UnicastRemoteObject; + +import chat.Chat; + +public class Server { + public static void main(String [] args) { + try { + ChatApp ca = new ChatApp(); + Chat h_stub = (Chat) UnicastRemoteObject.exportObject(ca, 0); + + Registry registry; + if (args.length > 0) { + int port = Integer.parseInt(args[1]); + registry = LocateRegistry.createRegistry(port); // Create registry if not already running + System.out.println("RMI Registry started on port " + port); + } else { + registry = LocateRegistry.createRegistry(2099); // Default port + System.out.println("RMI Registry started on port 2099"); + } + + registry.rebind("ChatService", h_stub); + System.out.println("Server ready"); + + } catch (Exception e) { + System.err.println("Error on server :" + e) ; + e.printStackTrace(); + } + } +}