Server.java 2.85 KB
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<Connection,String> activeConnections;
	
	public Server(String ip, int port, int rS)
	{
		try
		{
			ss = new MyServerSocket();
			lock = new ReentrantLock();
			activeConnections = new ConcurrentHashMap<Connection,String>();
			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<Connection> connections = activeConnections.keySet();
		Iterator<Connection> 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<Connection> conns = activeConnections.keySet();
		Iterator<Connection> it = conns.iterator();
		while(it.hasNext())
		{
			it.next().finish();
		}
	}
	
	public void killServer()
	{
		kill = true;
		ss.close();
		finishConnections();
	}
}