package com.university.chat.Server; import com.university.chat.Common.ChatMessage; import com.university.chat.Common.FileMessage; import com.university.chat.Common.MessageType; import java.io.File; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.Socket; import java.nio.file.Files; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class ClientSession implements Runnable { private String username; private ObjectOutputStream out = null; private ObjectInputStream in = null; private final Socket socket; private final UserManager userManage; private final Lock L = new ReentrantLock(); public ClientSession(Socket socket, UserManager userManager) { this.socket = socket; this.userManage = userManager; try { out = new ObjectOutputStream(socket.getOutputStream()); in = new ObjectInputStream(socket.getInputStream()); } catch (IOException e) { System.out.println(e.getMessage()); } } @Override public void run() { try { ChatMessage loginmsg = (ChatMessage) in.readObject(); username = loginmsg.getSender(); if(loginmsg.getType() != MessageType.LOGIN){ out.writeObject(new ChatMessage(MessageType.LOGIN_FAILED , "server" , username,"login failed")); socket.close(); return; } FileManager.createUserFolders(username); out.writeObject(new ChatMessage(MessageType.LOGIN_SUCCESS , "server" , username , "welcome to messanger login succes")); System.out.println(username + " connected"); userManage.addUser(username , this); while (true){ Object inputobj = in.readObject(); if(inputobj == null){ continue; } if(inputobj instanceof ChatMessage msg){ handleChatMessage(msg); } else if (inputobj instanceof FileMessage filemsg) { handleFileMessage(filemsg); } } } catch (Exception e) { System.out.println("Disconnected: " + username); System.out.println(e.getMessage()); } finally { if(username != null) { userManage.removeUser(username); } try { socket.close(); } catch (IOException e) { throw new RuntimeException(e); } } } private void handleChatMessage(ChatMessage msg) throws IOException { switch (msg.getType()) { case PUBLIC_MESSAGE -> { for(ClientSession cs : userManage.getAllSessions()){ if(cs != this){ cs.sendMessage(msg); } } } case PRIVATE_MESSAGE -> { ClientSession cs = userManage.getUser(msg.getReceiver()); if (cs != null) { cs.sendMessage(msg); } } case USER_LIST -> { ClientSession cs = userManage.getUser(msg.getSender()); ChatMessage listReply = new ChatMessage(MessageType.USER_LIST, "server", username, userManage.listUsers()); if (cs != null) { cs.sendMessage(listReply); } } } } private void handleFileMessage(FileMessage fileMsg) throws IOException { // Storing the file var sentPath = FileManager.getSentPath(fileMsg.getSender(), fileMsg.getFilename()); var recvPath = FileManager.getReceivedPath(fileMsg.getReceiver(), fileMsg.getFilename()); Files.write(sentPath, fileMsg.getData()); Files.write(recvPath, fileMsg.getData()); ClientSession cs = userManage.getUser(fileMsg.getReceiver()); if(cs != null){ cs.sendMessage(fileMsg); } System.out.println("Server received file: " + fileMsg.getFilename() + " with size: " + fileMsg.getData().length); } public void sendMessage(Object object) { try { L.lock(); out.writeObject(object); out.flush(); } catch (IOException e) { System.out.println(e.getMessage()); } finally { L.unlock(); } } }