|
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))
{
|
|
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
{
|
|
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
|
}
|