package pad.prac2; import java.io.IOException; import java.util.Iterator; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class Server { private MyServerSocket ss; private int roomSize; private boolean kill; private Connection[] workerPool; private int freeWorkers; private Lock lock; private Condition availableWorkers; private ConcurrentHashMap activeConnections; public Server(String ip, int port, int rS) { try { ss = new MyServerSocket(); lock = new ReentrantLock(); activeConnections = new ConcurrentHashMap(); roomSize = rS; freeWorkers = roomSize; kill = false; availableWorkers = lock.newCondition(); workerPool = new Connection[roomSize]; for(int i = 0; i < roomSize; i++) { workerPool[i] = new Connection(this); workerPool[i].start(); } ss.bind(ip, port); } catch(IOException ioExc) { System.out.println("TCP: Error initializating server socket"); } } public void sendToChat(Connection origin, String message) { lock.lock(); String nickname = activeConnections.get(origin); Set connections = activeConnections.keySet(); Iterator it = connections.iterator(); Connection conn; while(it.hasNext()) { conn = it.next(); if(conn != origin) { conn.sendMessage(nickname + ": " + message); } } lock.unlock(); } public void startServer() { while(!kill) { MySocket incoming = ss.accept(); if(incoming != null) { System.out.println("Accepted connection from " + incoming.getInetAddress()); startWorker(incoming); } } } public void startWorker(MySocket s) { lock.lock(); while(freeWorkers == 0) { try { lock.unlock(); availableWorkers.await(); lock.lock(); } catch(InterruptedException intExc) { intExc.printStackTrace(); } } workerPool[roomSize - freeWorkers].setSock(s); workerPool[roomSize - freeWorkers].awake(); workerPool[roomSize - freeWorkers] = null; freeWorkers--; lock.unlock(); } public String getNickname(Connection c) { return activeConnections.get(c); } public void finishWorker(Connection c) { lock.lock(); freeWorkers++; workerPool[roomSize - freeWorkers] = c; availableWorkers.signal(); lock.unlock(); } public void addToChatroom(Connection c, String nickName) { activeConnections.put(c, nickName); System.out.println(nickName + " has entered the room"); } public void finishConnections() { Set conns = activeConnections.keySet(); Iterator it = conns.iterator(); while(it.hasNext()) { it.next().finish(); } } public void killServer() { kill = true; ss.close(); finishConnections(); } }