Собственно - если скучно кому, рутина там заела или еще что - милости прошу.
Хинт от валидатора :
"Метод clientHandshake() должен отправлять новое сообщение (MessageType.USER_NAME, getUserName()) используя connection, если тип принятого сообщения равен MessageType.NAME_REQUEST."
Собственно вот :
case NAME_REQUEST: {
Message userNameResponse = new Message(MessageType.USER_NAME, getUserName());
connection.send(userNameResponse);
break;
}
P.S. : Логика, которая нас интересует - в классе Clientpackage 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) {
int port = ConsoleHelper.readInt();
try (ServerSocket serverSocket = new ServerSocket(port)) {
System.out.println("Server is running...");
while (true) {
new Handler(serverSocket.accept()).start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void sendBroadcastMessage(Message message) {
for (Map.Entry<String, Connection> client :
connectionMap.entrySet()) {
try {
client.getValue().send(message);
} catch (IOException e) {
System.err.println("Failed to send message to " + client.getKey());
}
}
}
private static class Handler extends Thread {
private Socket socket;
public Handler(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
Connection connection = null;
String userName = null;
ConsoleHelper.writeMessage("Connection established with " + socket.getRemoteSocketAddress());
try {
connection = new Connection(socket);
// ConsoleHelper.writeMessage("Connection established with " + connection.getRemoteSocketAddress());
userName = serverHandshake(connection);
Server.sendBroadcastMessage(new Message(MessageType.USER_ADDED, userName));
notifyUsers(connection, userName);
serverMainLoop(connection, userName);
} catch (IOException | ClassNotFoundException e) {
System.err.printf("Remote server communication error %n%s", e);
} finally {
if (connection != null) {
try {
connection.close();
} catch (IOException ignored) {
ignored.printStackTrace();
}
}
if (userName != null) {
connectionMap.remove(userName);
Server.sendBroadcastMessage(new Message(MessageType.USER_REMOVED, userName));
}
}
if (connection != null) {
ConsoleHelper.writeMessage("Remote server has disconnected");
}
}
private String serverHandshake(Connection connection) throws
IOException, ClassNotFoundException {
Message receivedMessage;
do {
connection.send(new Message(MessageType.NAME_REQUEST));
receivedMessage = connection.receive();
} while (receivedMessage.getType() != MessageType.USER_NAME ||
receivedMessage.getData().isEmpty() || connectionMap.containsKey(receivedMessage.getData()));
connectionMap.put(receivedMessage.getData(), connection);
connection.send(new Message(MessageType.NAME_ACCEPTED));
return receivedMessage.getData();
}
/*
Actually - notify this user about other users
Method name mismatch
*/
private void notifyUsers(Connection connection, String username) throws IOException {
for (Map.Entry<String, Connection> userConnection :
connectionMap.entrySet()) {
if (!userConnection.getKey().equals(username)) {
connection.send(new Message(MessageType.USER_ADDED, userConnection.getKey()));
}
}
}
private void serverMainLoop(Connection connection, String userName) throws IOException, ClassNotFoundException {
while (true) {
Message receivedFromUser = connection.receive();
if (receivedFromUser.getType() == MessageType.TEXT) {
Server.sendBroadcastMessage(
new Message(MessageType.TEXT,
String.format("%s: %s", userName, receivedFromUser.getData())));
} else {
ConsoleHelper.writeMessage(
String.format("Message type error: %s, from user: %s",
receivedFromUser.getType(), userName));
}
}
}
}
}