-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathServer.java
More file actions
132 lines (107 loc) · 5.68 KB
/
Server.java
File metadata and controls
132 lines (107 loc) · 5.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.logging.Handler;
public class Server {
private static Map<String, Connection> connectionMap = new ConcurrentHashMap<>(); //thread-safe map
public static void sendBroadcastMessage(Message message){
try {
for (Map.Entry<String, Connection> connectionEntry : connectionMap.entrySet()) { //send a message to all connections from the map
connectionEntry.getValue().send(message);
}
}
catch (IOException e){
e.printStackTrace();
System.out.println("Сообщение не было отправлено!");
}
}
private static class Handler extends Thread { //class Handler conducts the protocol of interactions with the client
private Socket socket;
public void run(){ //main method run which implements all following methods
ConsoleHelper.writeMessage("Соединение с сервером было установлено пользователем " + socket.getRemoteSocketAddress());
String userName = null;
try(Connection connection = new Connection(this.socket)) {
//the result is String(userName)
userName = serverHandshake(connection);
//send to all users the message about new user555
sendBroadcastMessage(new Message(MessageType.USER_ADDED, userName));
//notify user about all current users
notifyUsers(connection,userName);
//invoke main loop
serverMainLoop(connection, userName);
} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
ConsoleHelper.writeMessage("Ошибка при обмене данными с удаленным адресом " + socket.getRemoteSocketAddress());
}
finally {
if(userName!=null) {
connectionMap.remove(userName);
sendBroadcastMessage(new Message(MessageType.USER_REMOVED, userName));
}
}
ConsoleHelper.writeMessage("Соединение с удаленным адресом " + socket.getRemoteSocketAddress() + " закрыто");
}
public Handler(Socket socket) {
this.socket = socket;
}
private String serverHandshake(Connection conncetion) throws IOException, ClassNotFoundException {
while (true){
conncetion.send(new Message(MessageType.NAME_REQUEST));
Message message = conncetion.receive();
String userName = message.getData();
if(message.getType() != MessageType.USER_NAME){
ConsoleHelper.writeMessage("Получено сообщение от " + socket.getRemoteSocketAddress() + ". Формат сообщение не верен"); // wrong format of the name
continue;
}
if(userName.isEmpty()){
ConsoleHelper.writeMessage("Пустое имя было введено " + socket.getRemoteSocketAddress()); //empty name
continue;
}
if(connectionMap.containsKey(userName)){
ConsoleHelper.writeMessage("Попытка подключения к серверу с уже использованным именем от " + socket.getRemoteSocketAddress()); //name already exists
continue;
}
connectionMap.put(userName, conncetion);
conncetion.send(new Message(MessageType.NAME_ACCEPTED));
return userName;
}
}
private void notifyUsers(Connection connection, String userName) throws IOException{ //notify all users that a person has just connected
for(Map.Entry<String, Connection> connectionEntry: connectionMap.entrySet()){
if(connectionEntry.getKey()!=userName){ //don't send information to user who just connected
connection.send(new Message(MessageType.USER_ADDED, connectionEntry.getKey())); //notify all users
}
}
}
private void serverMainLoop(Connection connection, String userName) throws IOException, ClassNotFoundException{ //Main method
while (true){
Message message = connection.receive();
if(message.getType()==MessageType.TEXT){
sendBroadcastMessage(new Message(MessageType.TEXT,userName + ": " + message.getData()));
}
else{
ConsoleHelper.writeMessage("Получено сообщение от " + socket.getRemoteSocketAddress() + ". Тип сообщения не соответсвует протоколу.");
}
}
}
}
public static void main(String[] args) {
ConsoleHelper.writeMessage("Введите порт сервера:");
int port = ConsoleHelper.readInt();
try(ServerSocket serverSocket = new ServerSocket(port)){
ConsoleHelper.writeMessage("Чат сервера запущен.");
while(true){
Socket socket = serverSocket.accept();
new Handler(socket).start();
}
}
catch (IOException e){
e.printStackTrace();
}
}
}