task 5 started.

This commit is contained in:
2025-12-22 00:26:19 +01:00
parent e8f1271f06
commit 01bd4ba693
13 changed files with 293 additions and 14 deletions

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,66 @@
package client;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.Scanner;
import common.ClientInterface;
import common.ServerInterface;
public class Client extends UnicastRemoteObject implements ClientInterface {
private String clientId;
private ServerInterface server;
protected Client(String clientId, ServerInterface server) throws RemoteException {
super();
this.clientId = clientId;
this.server = server;
server.registerClient(clientId, this);
}
public void sendMessage(String toId, String message) throws RemoteException {
server.sendMessage(clientId, toId, message);
}
public void blockClient(String blockedId) throws RemoteException {
server.blockClient(clientId, blockedId);
}
@Override
public void receiveMessage(String fromId, String message) throws RemoteException {
System.out.println("[" + fromId + "]: " + message);
}
// entry point
public static void main(String[] args) {
try (Scanner scanner = new Scanner(System.in)) {
// get client ID and server info
System.out.print("Enter your client ID: ");
String clientId = scanner.nextLine();
// get recipient ID
System.out.print("Enter recipient ID: ");
String toId = scanner.nextLine();
Registry registry = LocateRegistry.getRegistry("localhost", 1099);
ServerInterface server = (ServerInterface) registry.lookup("ChatServer");
Client client = new Client(clientId, server);
System.out.print("You can start chatting now. Type your messages below: Type exit to log out\n");
while (true) {
String msg = scanner.nextLine();
if (msg.equalsIgnoreCase("exit")) {
System.out.println("Logging out...");
break;
}
client.sendMessage(toId, msg);
}
} catch (Exception e) {
System.err.println("Client exception: " + e.getMessage());
}
}
}

View File

@@ -0,0 +1,16 @@
package common;
/**
* ClientInterface interface
*
* @author Tinsae Ghilay
*
*/
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface ClientInterface extends Remote {
void receiveMessage(String fromId, String message) throws RemoteException;
}

View File

@@ -0,0 +1,23 @@
package common;
/**
* ClientInterface interface
*
* @author Tinsae Ghilay
*
*/
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.List;
public interface ServerInterface extends Remote {
void registerClient(String clientId, ClientInterface client) throws RemoteException;
void sendMessage(String fromId, String toId, String message) throws RemoteException;
void blockClient(String clientId, String blockedId) throws RemoteException;
List<String> getOfflineMessages(String clientId) throws RemoteException;
}

View File

@@ -0,0 +1,69 @@
package server;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.RemoteException;
import java.util.*;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
// import interfaces
import common.ClientInterface;
import common.ServerInterface;
public class Server extends UnicastRemoteObject implements ServerInterface {
private Map<String, ClientInterface> onlineClients = new HashMap<>();
private Map<String, List<String>> offlineMessages = new HashMap<>();
private Map<String, Set<String>> blockedClients = new HashMap<>();
protected Server() throws RemoteException {
super();
}
@Override
public synchronized void registerClient(String clientId, ClientInterface client) throws RemoteException {
onlineClients.put(clientId, client);
blockedClients.putIfAbsent(clientId, new HashSet<>());
// Send any offline messages
List<String> messages = offlineMessages.getOrDefault(clientId, new ArrayList<>());
for (String msg : messages) {
client.receiveMessage("Offline", msg);
}
offlineMessages.remove(clientId);
}
@Override
public synchronized void sendMessage(String fromId, String toId, String message) throws RemoteException {
// Check if recipient blocked sender
Set<String> blocked = blockedClients.getOrDefault(toId, Collections.emptySet());
if (blocked.contains(fromId))
return;
ClientInterface recipient = onlineClients.get(toId);
if (recipient != null) {
recipient.receiveMessage(fromId, message);
} else {
// Store message for offline delivery
offlineMessages.putIfAbsent(toId, new ArrayList<>());
offlineMessages.get(toId).add(fromId + ": " + message);
}
}
@Override
public synchronized void blockClient(String clientId, String blockedId) throws RemoteException {
blockedClients.putIfAbsent(clientId, new HashSet<>());
blockedClients.get(clientId).add(blockedId);
}
@Override
public synchronized List<String> getOfflineMessages(String clientId) throws RemoteException {
return offlineMessages.getOrDefault(clientId, Collections.emptyList());
}
// entry point
public static void main(String[] args) throws Exception {
Server server = new Server();
Registry registry = LocateRegistry.createRegistry(1099);
registry.rebind("ChatServer", server);
System.out.println("Chat server running...");
}
}