Я работаю над приложением Java Client/Server Chat, которое позволяет пользователям внутри локальной сети общаться между ними.Получение ссылки на другой поток на основе некоторого параметра
В серверном приложении у меня есть основной класс, который создает различный поток всякий раз, когда клиент подключается к серверу. Таким образом, я в основном открываю TCP-соединение с каждым клиентом, работающим в отдельном потоке.
У меня возникли проблемы с отправкой сообщений. Когда пользователь отправляет на сервер новое сообщение + место назначения, сервер должен найти поток, который имеет соединение с конечным пользователем, и отправить ему это сообщение. Как мне это сделать. Я связал каждый поток с пользовательским объектом, поэтому мне нужно сделать что-то вроде findThreadByUser (user), и после получения ссылки просто вызовите метод отправки сообщения. Как мне это сделать?
Вот части класса ConnectionHandler, который реализует Runnable. Я хочу получить доступ к конкретному экземпляру класса и, более конкретно, к методу sendToClient(String message)
в конце его (метод внешнего запуска). Я попытался с HashMap для хранения пользователя и нить, но я не могу получить доступ к методу sendToClient(String message)
public class ConnectionHandler implements Runnable {
protected Socket socket;
private ServerData serverData;
private User currentUser;
BufferedReader inFromClient;
PrintStream outToClient;
String clientSentence;
String peerIp;
String peerHostName;
public ConnectionHandler(Socket socketToHandle, ServerData serverData) {
socket = socketToHandle;
this.serverData = serverData;
inFromClient = null;
outToClient = null;
currentUser = null;
clientSentence = " ";
}
@Override
public void run() {
peerIp = socket.getInetAddress().getHostAddress();
peerHostName = socket.getInetAddress().getHostName();
try {
outToClient = new PrintStream(socket.getOutputStream(), true);
/* Create a reading stream to the socket */
inFromClient = new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (IOException ex) {
Logger.getLogger(ConnectionHandler.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("Error creating buffered handles.");
}
System.out.println("Handling connection to client at " + peerIp + " --");
Runnable r1 = new Runnable() {
public void run() {
while (true) {
try {
/* Read client's message through the socket's input buffer */
clientSentence = inFromClient.readLine();
} catch (IOException e) {
System.out.println(socket.getInetAddress() + "-" + peerIp + " broke the connection.");
break;
}
/* Output to screen the message received by the client */
System.out.println("Message Received: " + clientSentence);
List<String> processedClientSentence = ClientMessageProcessor.process(clientSentence);
if (processedClientSentence.get(0).equals(new String("LOGIN"))) {
String result = ServerActions.login(peerIp, peerHostName, processedClientSentence.get(1), serverData);
if (result.equals("success")) {
currentUser = serverData.getUserByIP(peerIp);
outToClient.println("USERS \"" + ServerActions.getUsers(serverData) + "\"");
} else {
outToClient.println("ERROR \'" + result + "\'");
}
} else if (processedClientSentence.get(0).equals(new String("GETUSERS"))) {
outToClient.println("USERS \"" + ServerActions.getUsers(serverData) + "\"");
} else if (processedClientSentence.get(0).equals(new String("USERINFO"))) {
} else if (processedClientSentence.get(0).equals(new String("MESSAGE"))) {
ServerActions.sendMessage(currentUser/*.getUserName()*/, processedClientSentence.get(1), processedClientSentence.get(2), serverData);
} else if (processedClientSentence.get(0).equals(new String("LOGOUT"))) {
} else {
}
}
}
};
new Thread(r1).start();
}
public void sendToClient(String message) {
outToClient.println(message);
}
}
Почему вы не можете создать поле 'Thread' в каждом' UserObject'? – alaster
Почему вы не держите карту, пользователь и соответствующий поток, и ссылаетесь на эту карту, чтобы найти поток, связанный с конкретным пользователем. – Subin
@SubinS Итак, в основном вы хотите связать пользователя с потоками в классе Server Data, а затем вызвать поток следующим образом: 'for (Thread t: Thread.getAllStackTraces(). KeySet()) if (t.getId() == id) // отправить сообщение'? Спасибо за ваши ответы – interboy