Здравствуйте! Подскажите пожалуйста что не так написал?
package com.javarush.task.task30.task3008;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class Server {
private static Map<String, Connection> connectionMap = new ConcurrentHashMap<>();
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(ConsoleHelper.readInt());
System.out.println("Server is started");
while (true) {
try {
Socket socket = serverSocket.accept();
Handler handler = new Handler(socket);
handler.start();
} catch (Exception ex) {
System.out.println(ex.getStackTrace());
serverSocket.close();
break;
}
}
}
public static void sendBroadcastMessage(Message message) {
for (String s : connectionMap.keySet()) {
Connection connection = connectionMap.get(s);
try {
connection.send(message);
} catch (IOException e) {
System.out.println("Ошибка отправки");
}
}
}
private static class Handler extends Thread {
private Socket socket;
public Handler(Socket socket) {
this.socket = socket;
}
private String serverHandshake(Connection connection) throws IOException, ClassNotFoundException {
String username;
while (true) {
Message outMessage = new Message(MessageType.NAME_REQUEST, "Как вас зовут");
connection.send(outMessage);
Message inMessage = connection.receive();
if (inMessage.getType() != MessageType.USER_NAME) continue;
if (inMessage.getData().isEmpty()) continue;
if (connectionMap.containsKey(inMessage.getData())) continue;
username = inMessage.getData();
connectionMap.put(username, connection);
connection.send(new Message(MessageType.NAME_ACCEPTED, "Имя принято"));
return username;
}
}
private void notifyUsers(Connection connection, String userName) throws IOException {
/**
*1) Пройтись по connectionMap.
* 2) У каждого элемента из п.1 получить имя клиента, сформировать команду с типом USER_ADDED и полученным именем.
* 3) Отправить сформированную команду через connection.
* 4) Команду с типом USER_ADDED и именем равным userName отправлять не нужно, пользователь и так имеет информацию о себе.
*/
for (String s : connectionMap.keySet()) {
String name = s;
Message message = new Message(MessageType.USER_ADDED, name);
if (!userName.equals(name)) connection.send(message);
}
}
private void serverMainLoop(Connection connection, String userName) throws IOException, ClassNotFoundException {
Message message = null;
Message newMessage = null;
while (true) {
message = connection.receive();
if (message.getType() == MessageType.TEXT) {
newMessage = new Message(MessageType.TEXT, userName + ": " + message.getData());
sendBroadcastMessage(newMessage);
}
ConsoleHelper.writeMessage("Неверный тип сообщения");
}
}
/*
+1. Выводить сообщение, что установлено новое соединение с удаленным адресом, который можно получить с помощью метода getRemoteSocketAddress().
+2. Создавать Connection, используя поле socket.
+3. Вызывать метод, реализующий рукопожатие с клиентом, сохраняя имя нового клиента.
+4. Рассылать всем участникам чата информацию об имени присоединившегося участника (сообщение с типом USER_ADDED).
Подумай, какой метод подойдет для этого лучше всего.
+5. Сообщать новому участнику о существующих участниках.
+6. Запускать главный цикл обработки сообщений сервером.
7. Обеспечить закрытие соединения при возникновении исключения.
8. Отловить все исключения типа IOException и ClassNotFoundException, вывести в консоль информацию, что произошла ошибка при обмене данными с удаленным адресом.
9. После того как все исключения обработаны, если п.11.3 отработал и возвратил нам имя, мы должны удалить запись для этого имени из connectionMap и разослать всем остальным участникам сообщение с типом USER_REMOVED и сохраненным именем.
10. Последнее, что нужно сделать в методе run() - вывести сообщение, информирующее что соединение с удаленным адресом закрыто.*/
public void run() {
System.out.println("Установленно соединение с " + socket.getRemoteSocketAddress());
String userName = null;
try (Connection connection = new Connection(socket)) {
userName = serverHandshake(connection);
sendBroadcastMessage(new Message(MessageType.USER_ADDED, userName));
notifyUsers(connection, userName);
serverMainLoop(connection, userName);
} catch (IOException | ClassNotFoundException e) {
ConsoleHelper.writeMessage("Произошла ошибка при обмене данными с удаленным адресом");
}
if (userName != null && connectionMap.containsKey(userName)) {
connectionMap.remove(userName);
sendBroadcastMessage(new Message(MessageType.USER_REMOVED, userName));
}
ConsoleHelper.writeMessage("Соединение закрыто");
}
}
}