Blame view

JChatServerV2/src/pad/prac2/Server.java 4.63 KB
1
2
3
package pad.prac2;

import java.io.IOException;
4
import java.util.Collection;
5
import java.util.Iterator;
6
import java.util.Set;
7
import java.util.concurrent.ConcurrentHashMap;
8
9
10
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
11
12
13
14

public class Server
{
	private MyServerSocket ss;
15
	private int roomSize;
16
17
18
19
20
21
	private boolean kill;
	private Connection[] workerPool;
	private int freeWorkers;
	private Lock lock;
	private Condition availableWorkers;
	private ConcurrentHashMap<Connection,String> activeConnections;
22
23

	public Server(String ip, int port, int rS)
24
25
26
	{
		try
		{
27
			ss = new MyServerSocket();
28
29
			lock = new ReentrantLock();
			activeConnections = new ConcurrentHashMap<Connection,String>();
30
			roomSize = rS;
31
32
33
34
35
36
37
38
39
40
			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);
41
42
43
44
45
46
		}
		catch(IOException ioExc)
		{
			System.out.println("TCP: Error initializating server socket");
		}
	}
47
48
	public void startServer()
49
	{
50
		while(!kill)
51
		{
52
			try
53
			{
54
				MySocket incoming = ss.accept();
55
56
				startWorker(incoming);
			}
57
58
59
60
61
62
63
64
			catch(IOException ioExc)
			{
				if(!kill)
				{
					System.out.println("TCP: Error accepting connection");
					break;
				}
			}
65
		}
66
67
68
69
70
71
72

	}

	public void startWorker(MySocket s)
	{
		lock.lock();
		while(freeWorkers == 0)
73
		{
74
75
			try
			{
76
				s.sendMsg("CHATFULL");
77
78
79
				s.close();
				lock.unlock();
				return;
80
			}
81
82
83
84
			catch(IOException ioExc)
			{
				System.out.println("TCP: Error while sending message to client");
			}
85
		}
86
87
88
89
90
91
92
93
94
95
		workerPool[roomSize - freeWorkers].setSock(s);
		workerPool[roomSize - freeWorkers].awake();
		workerPool[roomSize - freeWorkers] = null;
		freeWorkers--;
		lock.unlock();
	}

	public void finishWorker(Connection c)
	{
		lock.lock();
96
		removeFromChatroom(c);
97
98
99
100
101
102
		freeWorkers++;
		workerPool[roomSize - freeWorkers] = c;
		availableWorkers.signal();
		lock.unlock();
	}
103
104
105
106
107
108
109
110
111
112
113
114
115
	public void sendTo(Connection orig, String nick, String msg) throws IOException, ChatException
	{
		lock.lock();
		System.out.println("FROM " + getNickname(orig) + " TO " + nick + ": " + msg);
		msg = getNickname(orig) + ": " + msg;
		Set<Connection> conns = activeConnections.keySet();
		Iterator<Connection> it = conns.iterator();
		Connection dest;
		while(it.hasNext())
		{
			dest = it.next();
			if(getNickname(dest).equals(nick))
			{
Imanol-Mikel Barba Sabariego authored
116
				dest.sendMessage("1"+msg);
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
				lock.unlock();
				return;
			}
		}
		lock.unlock();
		throw new ChatException("No such nickname");
	}

	public void sendToChat(Connection origin, String message) throws IOException
	{
		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)
			{
137
				conn.sendMessage("0"+nickname + ": " + message);
138
139
140
141
142
143
144
145
146
147
			}
		}
		lock.unlock();
	}

	public String getNickname(Connection c)
	{
		return activeConnections.get(c);
	}
148
149
150
151
152
153
154
155
156
157
158
	public void notifyAllConnections()
	{
		lock.lock();
		Set<Connection> connections = activeConnections.keySet();
		Iterator<Connection> it = connections.iterator();
		Connection conn;
		while(it.hasNext())
		{
			conn = it.next();
			try
			{
Imanol-Mikel Barba Sabariego authored
159
				conn.sendMessage("USERLIST"+nickList());
160
161
162
163
164
165
166
167
168
			}
			catch(IOException ioExc)
			{
				System.out.println("TCP: Error writing to socket");
			}
		}
		lock.unlock();
	}
169
170
171
172
	public void addToChatroom(Connection c, String nickName)
	{
		activeConnections.put(c, nickName);
		System.out.println(nickName + " has entered the room");
173
		notifyAllConnections();
174
175
	}
176
	private void removeFromChatroom(Connection c)
177
	{
178
		activeConnections.remove(c);
179
		notifyAllConnections();
180
181
182
183
184
185
186
187
188
189
190
	}

	public boolean isOnline(String nick)
	{
		return activeConnections.contains(nick);
	}

	public String listOnline()
	{
		lock.lock();
		String ret = new Integer(activeConnections.size()).toString();
191
192
193
194
195
196
197
198
199
		ret += " people currently online:\n";
		ret += nickList();
		lock.unlock();
		return ret;
	}

	public String nickList()
	{
		String ret = "";
200
201
		Collection<String> nickNames = activeConnections.values();
		Iterator<String> it = nickNames.iterator();
202
203
		while(it.hasNext())
		{
204
			ret += it.next();
205
			ret += "\n";
206
		}
207
		return ret;
208
209
210
211
	}

	public void killServer()
	{
212
		kill = true;
213
		ss.close();
214
		finishConnections();
215
	}
216
217
218
219
220
221
222
223
224
225

	public void finishConnections()
	{
		Set<Connection> conns = activeConnections.keySet();
		Iterator<Connection> it = conns.iterator();
		while(it.hasNext())
		{
			it.next().finish();
		}
	}
226
}