Вот код, который "не прошёл":
package com.javarush.task.task30.task3008;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class Server {
private static Map<String, Connection> connectionMap = new ConcurrentHashMap<>();
public static void sendBroadcastMessage(Message message) {
for(Map.Entry<String, Connection> pair : connectionMap.entrySet()) {
try {
pair.getValue().send(message);
}
catch (Exception e) {
System.out.println("Ошибка при отправке сообщения!" + e.getMessage());
}
}
}
public static void main(String[] args) {
int port = ConsoleHelper.readInt();
try (ServerSocket serverSocket = new ServerSocket(port)){
System.out.println("Server started");
while (true) {
Handler handler = new Handler(serverSocket.accept());
handler.start();
}
}
catch (Exception e){
System.out.println(e.getMessage());
}
}
private static class Handler extends Thread {
private Socket socket;
public Handler(Socket socket) {
this.socket = socket;
}
private String serverHandshake(Connection connection) throws IOException, ClassNotFoundException {
while (true){
connection.send(new Message(MessageType.NAME_REQUEST, "Введите имя"));
Message answer = connection.receive();
if (answer.getType() != MessageType.USER_NAME) {
continue;
}
String userName = answer.getData();
if (userName == null || userName.isEmpty()) {
continue;
}
if (connectionMap.containsKey(userName)) {
continue;
}
connectionMap.put(userName, connection);
connection.send(new Message(MessageType.NAME_ACCEPTED));
return userName;
}
}
private void notifyUsers(Connection connection, String userName) throws IOException {
for(Map.Entry<String, Connection> pair : connectionMap.entrySet()) {
String key = pair.getKey();
if(key != userName) {
Message message = new Message(MessageType.USER_ADDED, key);
connection.send(message);
}
}
}
private void serverMainLoop(Connection connection, String userName) throws IOException, ClassNotFoundException {
while(true) {
Message message = connection.receive();
if (message != null) {
if (message.getType() == MessageType.TEXT) {
String text = userName + ": " + message.getData();
Message message1 = new Message(MessageType.TEXT, text);
sendBroadcastMessage(message1);
}
else {
ConsoleHelper.writeMessage("Error!");
}
}
}
}
@Override
public void run() {
ConsoleHelper.writeMessage("Соединение установлено с" + socket.getRemoteSocketAddress());
String userName = null;
if(socket != 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.remove(userName);
sendBroadcastMessage(new Message(MessageType.USER_REMOVED, userName));
}
}
ConsoleHelper.writeMessage("Соединение закрыто");
}
}
}
А вот код, который я взял из "помощи" и модифицировал (этот код прошёл) :
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 {
int port = ConsoleHelper.readInt();
try (ServerSocket serverSocket = new ServerSocket(port)){
System.out.println("Server started");
while (true) {
Handler handler = new Handler(serverSocket.accept());
handler.start();
}
}
catch (Exception e){
System.out.println(e.getMessage());
}
}
public static void sendBroadcastMessage(Message message) {
for (Map.Entry<String, Connection> pair : connectionMap.entrySet()) {
try {
pair.getValue().send(message);
} catch (IOException e) {
System.out.println("Message not sended. Error: " + e.getMessage());
}
}
}
private static class Handler extends Thread {
private Socket socket;
public Handler (Socket socket) {
this.socket = socket;
}
public void run() {
ConsoleHelper.writeMessage(String.valueOf(socket.getRemoteSocketAddress()));
String name = null;
try (Connection connection = new Connection(socket)) {
name = serverHandshake(connection);
sendBroadcastMessage(new Message(MessageType.USER_ADDED, name));
notifyUsers(connection, name);
serverMainLoop(connection, name);
}
catch (IOException | ClassNotFoundException e) {
ConsoleHelper.writeMessage("Произошла ошибка при обмене данными с удаленным адресом.");
}
if(name != null) {
connectionMap.remove(name);
sendBroadcastMessage(new Message(MessageType.USER_REMOVED, name));
}
ConsoleHelper.writeMessage("Connection is cosed!");
}
private String serverHandshake(Connection connection) throws IOException, ClassNotFoundException {
Message nameRequest = new Message(MessageType.NAME_REQUEST, "Введите, пожалуйста, ваше имя!");
Message query;
do {
connection.send(nameRequest);
query = connection.receive();
}
while (query.getType() != MessageType.USER_NAME
|| query.getData().isEmpty()
|| connectionMap.containsKey(query.getData()));
connectionMap.put(query.getData(), connection);
connection.send(new Message(MessageType.NAME_ACCEPTED, "Name accepted"));
return query.getData();
}
private void notifyUsers(Connection connection, String userName) throws IOException {
for (Map.Entry<String, Connection> pair : connectionMap.entrySet()) {
Message request = new Message(MessageType.USER_ADDED, pair.getKey());
if (!pair.getKey().equals(userName))
connection.send(request);
}
}
private void serverMainLoop(Connection connection, String userName) throws IOException, ClassNotFoundException {
while (true) {
Message clientMessage = connection.receive();
if (clientMessage.getType() == MessageType.TEXT)
sendBroadcastMessage(new Message(MessageType.TEXT, userName + ": " + clientMessage.getData()));
else
ConsoleHelper.writeMessage("Error!");
}
}
}
}
Проблема была именно в файле Server, поэтому не вижу смысла выкладывать остальные. Что не так в "неправильном" коде?
двигательцикл? :) Вот почему ты получил "Код работал слишком долго." Поправим тесты.