2012-06-17 2 views
0

Я работаю над приложением 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); 
} 

}

+0

Почему вы не можете создать поле 'Thread' в каждом' UserObject'? – alaster

+0

Почему вы не держите карту, пользователь и соответствующий поток, и ссылаетесь на эту карту, чтобы найти поток, связанный с конкретным пользователем. – Subin

+0

@SubinS Итак, в основном вы хотите связать пользователя с потоками в классе Server Data, а затем вызвать поток следующим образом: 'for (Thread t: Thread.getAllStackTraces(). KeySet()) if (t.getId() == id) // отправить сообщение'? Спасибо за ваши ответы – interboy

ответ

2

Храните объекты клиента в HashMap, UserName (который будет уникальным) в качестве ключа, и потока, связанного с ним как значение ... `

+0

Если OP нужен поток, чтобы получить «Пользователь», сохраните его как значение. –

+0

Можете ли вы увидеть изменение, которое я сделал на вопрос. Я пытался, как вы сказали, но я могу получить доступ к основным методам потока. Однако я хочу получить доступ к другому методу внутри класса, который реализует поток. Я добавил весь класс и объяснения к вопросу выше. Спасибо – interboy

-1

Почему бы не послать радиопередачу и пусть правильный клиент принять сообщение?

+1

Зачем? Просто потому, что это чат в локальной сети, это не значит, что вы никогда не захотите использовать его в нескольких подсетей (и это, конечно же, не означает, что вы всегда хотите, чтобы каждое личное сообщение отправлялось каждому клиенту). –

Смежные вопросы