I can't get past the timeout when calling
userName = serverHandshake(connection);
I commented that line out so I could fail the test and post my code but I usually run it without comments.
I'm also not sure where the removal of the user from map should be. Catch block, finally block or after the try-catch block entirely?package com.codegym.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) {
try (ServerSocket serverSocket = new ServerSocket(ConsoleHelper.readInt())) {
ConsoleHelper.writeMessage("Server is running");
while (true) {
try (Socket socket = serverSocket.accept()) {
new Handler(socket).start();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
} catch (Exception e) {
e.getMessage();
}
}
public static void sendBroadcastMessage (Message message) {
try {
for (Map.Entry<String, Connection> entry : connectionMap.entrySet()) {
Connection connection = entry.getValue();
connection.send(message);
}
} catch (IOException e) {
ConsoleHelper.writeMessage("Message couldn't be sent.");
}
}
private static class Handler extends Thread {
private Socket socket;
public Handler (Socket socket) {
this.socket = socket;
}
@Override
public void run() {
String userName = null;
ConsoleHelper.writeMessage("A connection has been established with " + socket.getRemoteSocketAddress());
try (Connection connection = new Connection(socket)) {
// userName = serverHandshake(connection);
sendBroadcastMessage(new Message(MessageType.USER_ADDED, userName));
notifyUsers(connection, userName);
serverMainLoop(connection, userName);
} catch (Exception e) {
ConsoleHelper.writeMessage("An error occurred while communicating with the remote address.");
} finally {
if (userName != null) connectionMap.remove(userName);
sendBroadcastMessage(new Message(MessageType.USER_REMOVED, userName));
}
ConsoleHelper.writeMessage("Connection with " + socket.getRemoteSocketAddress() + " closed.");
}
private String serverHandshake (Connection connection) throws IOException, ClassNotFoundException {
Message nameRequest = new Message(MessageType.NAME_REQUEST);
Message response;
do {
connection.send(nameRequest);
response = connection.receive();
} while (response == null ||
response.getType() != MessageType.USER_NAME ||
response.getData() == null ||
response.getData().isEmpty() ||
connectionMap.containsKey(response.getData()));
connectionMap.put(response.getData(), connection);
connection.send(new Message (MessageType.NAME_ACCEPTED));
return response.getData();
}
private void notifyUsers (Connection connection, String userName) throws IOException {
for (Map.Entry<String, Connection> entry : connectionMap.entrySet()) {
if (!entry.getKey().equals(userName)) {
connection.send(new Message(MessageType.USER_ADDED, entry.getKey()));
}
}
}
private void serverMainLoop (Connection connection, String userName) throws IOException, ClassNotFoundException {
while (true) {
Message received = connection.receive();
if (received.getType() == MessageType.TEXT) {
sendBroadcastMessage(new Message (received.getType(), userName + ": " + received.getData()));
} else {
ConsoleHelper.writeMessage("Error. Message type is not \"TEXT\".");
}
}
}
}
}