/*Не проходит валидацию по пункту 5. Метод clientMainLoop должен принимать сообщения от сервера до тех пор, пока тип сообщения равен MessageType.TEXT, MessageType.USER_REMOVED или MessageType.USER_ADDED.*/
package com.javarush.task.task30.task3008.client;
import com.javarush.task.task30.task3008.Connection;
import com.javarush.task.task30.task3008.ConsoleHelper;
import com.javarush.task.task30.task3008.Message;
import com.javarush.task.task30.task3008.MessageType;
import java.io.IOException;
/*** Created by User on 17.09.17.*/
public class Client {
protected Connection connection;
private volatile boolean clientConnected = false;
protected String getServerAddress() {
ConsoleHelper.writeMessage("Введите ip-адрес или localhost.");
return ConsoleHelper.readString();
}
protected int getServerPort() {
ConsoleHelper.writeMessage("Введите № порта сервера.");
return ConsoleHelper.readInt();
}
protected String getUserName() {
ConsoleHelper.writeMessage("Введите Ваше имя.");
return ConsoleHelper.readString();
}
protected boolean shouldSendTextFromConsole() {
return true;
}
protected SocketThread getSocketThread() {
return new SocketThread();
}
protected void sendTextMessage(String text) {
try {
connection.send(new Message(MessageType.TEXT, text));
} catch (IOException e) {
ConsoleHelper.writeMessage(e.getMessage());
clientConnected = false;
}
}
public void run() {
SocketThread socketThread = getSocketThread();
socketThread.setDaemon(true);
socketThread.start();
synchronized (this) {
try {
this.wait();
} catch (InterruptedException e) {
ConsoleHelper.writeMessage(e.getMessage());
return;
}
}
if (clientConnected) {
ConsoleHelper.writeMessage("Соединение установлено. Для выхода наберите команду ‘exit’.");
while (clientConnected) {
String text = ConsoleHelper.readString();
if (text.equals("exit")) {
clientConnected = false;
} else {
if (shouldSendTextFromConsole()) sendTextMessage(text);
}
}
} else {
ConsoleHelper.writeMessage("Произошла ошибка во время работы клиента.");
}
}
public static void main(String[] args) {
Client client = new Client();
client.run();
}
public class SocketThread extends Thread {
protected void processIncomingMessage(String message) {
ConsoleHelper.writeMessage(message);
}
protected void informAboutAddingNewUser(String userName) {
ConsoleHelper.writeMessage(userName.concat(" теперь с нами!"));
}
protected void informAboutDeletingNewUser(String userName) {
ConsoleHelper.writeMessage(userName.concat(" безвременно покинул чат. Помним. Скорбим."));
}
protected void notifyConnectionStatusChanged(boolean clientConnected) {
Client.this.clientConnected = clientConnected;
synchronized (Client.this) {
Client.this.notify();
}
}
protected void clientHandshake() throws IOException, ClassNotFoundException {
Message message;
while (true) {
try {
message = connection.receive();
} catch (Exception e) {
break;
}
if (message != null) {
if (message.getType() == MessageType.NAME_REQUEST) {
connection.send(new Message(MessageType.USER_NAME, getUserName()));
} else {
if (message.getType() == MessageType.NAME_ACCEPTED) {
notifyConnectionStatusChanged(true);
return;
} else {
throw new IOException("Unexpected MessageType");
}
}
}
}
}
protected void clientMainLoop() throws IOException, ClassNotFoundException {
Message message;
while (true) {
try {
message = connection.receive();
} catch (Exception e) {
break;
}
if (message != null) {
if (message.getType() == MessageType.TEXT) {
processIncomingMessage(message.getData());
} else {
if (message.getType() == MessageType.USER_ADDED) {
informAboutAddingNewUser(message.getData());
} else {
if (message.getType() == MessageType.USER_REMOVED) {
informAboutDeletingNewUser(message.getData());
} else {
break;
}
}
}
}
}
throw new IOException("Unexpected MessageType");
}
// protected void clientMainLoop() throws IOException, ClassNotFoundException {
// Message message;
// try {
// while (true) {
// try {
// message = connection.receive();
// } catch (Exception e) {
// break;
// }
// if (message != null) {
// switch (message.getType()) {
// case TEXT:
// processIncomingMessage(message.getData());
// break;
// case USER_ADDED:
// informAboutAddingNewUser(message.getData());
// break;
// case USER_REMOVED:
// informAboutDeletingNewUser(message.getData());
// break;
// default:
// throw new IOException("Unexpected MessageType");
// }
// }
// }
// }catch (Exception e){throw new IOException("Unexpected MessageType");}
// }
// protected void clientMainLoop() throws IOException, ClassNotFoundException {
// Message message;
// do {
// try {
// message = connection.receive();
// }catch (Exception e) {break;}
// if (message != null) {
// if (message.getType() == MessageType.TEXT) {
// processIncomingMessage(message.getData());
// } else {
// if (message.getType() == MessageType.USER_ADDED) {
// informAboutAddingNewUser(message.getData());
// } else {
// if (message.getType() == MessageType.USER_REMOVED) {
// informAboutDeletingNewUser(message.getData());
// } else {
// if (message.getType() != MessageType.TEXT
// && message.getType() != MessageType.USER_ADDED
// && message.getType() != MessageType.USER_REMOVED)
// break;
// }
// }
// }
// }
// } while (true);
// throw new IOException("Unexpected MessageType");
// }
// protected void clientMainLoop() throws IOException, ClassNotFoundException {
// Message message;
// MessageType messageType;
// String messageData;
// try {
// while (true) {
// message = connection.receive();
// messageType = message.getType();
// messageData = message.getData();
// switch (messageType) {
// case NAME_REQUEST:
// throw new IOException("Unexpected MessageType");
// case USER_NAME:
// throw new IOException("Unexpected MessageType");
// case NAME_ACCEPTED:
// throw new IOException("Unexpected MessageType");
// case TEXT:
// processIncomingMessage(messageData);
// break;
// case USER_ADDED:
// informAboutAddingNewUser(messageData);
// break;
// case USER_REMOVED:
// informAboutDeletingNewUser(messageData);
// break;
// default:
// message = connection.receive();
// }
//
// }
// }catch (Exception e){throw new IOException("Unexpected MessageType");}
// }
}
}
package com.javarush.task.task30.task3008;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Created by User on 16.09.17.
*/
public class Server {
private static Map<String, Connection> connectionMap = new ConcurrentHashMap<String, Connection>();
public static void sendBroadcastMessage(Message message) {
for (String s : connectionMap.keySet()) {
try {
connectionMap.get(s).send(message);
} catch (IOException e) {
ConsoleHelper.writeMessage("Возникли проблемы при отправке сообщения");
}
}
}
public static void main(String[] args) throws IOException {
ConsoleHelper.writeMessage("Введите номер порта сервера.");
int numberOfPort = ConsoleHelper.readInt();
ServerSocket serverSocket = new ServerSocket(numberOfPort);
ConsoleHelper.writeMessage("Сервер запущен.");
try {
while (true) {
new Handler(serverSocket.accept()).start();
// continue;
}
} catch (Exception e) {
ConsoleHelper.writeMessage(e.getMessage());
} finally {
serverSocket.close();
}
}
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) {
if (!answer.getData().isEmpty()) {
if (!connectionMap.containsKey(answer.getData())) {
connectionMap.put(answer.getData(), connection);
connection.send(new Message(MessageType.NAME_ACCEPTED));
return answer.getData();
}
}
}
}
}
private void sendListOfUsers(Connection connection, String userName) throws IOException {
for (String s : connectionMap.keySet()) {
if (!s.equals(userName)) {
connection.send(new Message(MessageType.USER_ADDED, s));
}
}
}
private void serverMainLoop(Connection connection, String userName) throws IOException, ClassNotFoundException {
while (true) {
Message message = connection.receive();
if (message.getType() == MessageType.TEXT)
sendBroadcastMessage(new Message(MessageType.TEXT, userName.concat(": " + message.getData())));
}
}
public void run() {
// ConsoleHelper.writeMessage("Established new connection with remote address " +
// socket.getRemoteSocketAddress());
// String clientName = null;
// try (Connection connection = new Connection(socket)){
// ConsoleHelper.writeMessage("Connection with port " + connection.getRemoteSocketAddress());
// clientName = serverHandshake(connection);
// sendBroadcastMessage(new Message(MessageType.USER_ADDED, clientName));
// sendListOfUsers(connection, clientName);
// serverMainLoop(connection, clientName);
// }catch (ClassNotFoundException e){
// ConsoleHelper.writeMessage(e.getMessage());
// }catch (IOException ioe){
// ConsoleHelper.writeMessage(ioe.getMessage());
// }finally{
// if (!clientName.equals(null))
// connectionMap.remove(clientName);
// sendBroadcastMessage(new Message(MessageType.USER_REMOVED, clientName));
// ConsoleHelper.writeMessage(String.format("Connection with remote address (%s) is closed.",
// socket.getRemoteSocketAddress()));
//
// }
// String userName = null;
if (socket != null && socket.getRemoteSocketAddress() != null)
ConsoleHelper.writeMessage("Установлено новое соединение с удаленным адресом:" +
" ".concat(socket.getRemoteSocketAddress().toString()));
String userName = null;
try (Connection connection = new Connection(socket)) {
// ConsoleHelper.writeMessage("Connection with port " + connection.getRemoteSocketAddress());
userName = serverHandshake(connection);
// Message message = new Message(MessageType.USER_ADDED, userName);
sendBroadcastMessage(new Message(MessageType.USER_ADDED, userName));
sendListOfUsers(connection, userName);
serverMainLoop(connection, userName);
} catch (IOException | ClassNotFoundException e) {
ConsoleHelper.writeMessage(e.getMessage());
// }
// try {
// socket.close();
// } catch (IOException e) {
// e.printStackTrace();
}finally {
if (userName != null)
connectionMap.remove(userName);
sendBroadcastMessage(new Message(MessageType.USER_REMOVED, userName));
}
ConsoleHelper.writeMessage("Cоединение с удаленным адресом закрыто.");
}
}
}