根据某个参数获取对另一个线程的引用

时间:2012-06-17 17:11:13

标签: java multithreading network-programming

我正在开发一个Java客户端/服务器聊天应用程序,它允许局域网内的用户在它们之间进行聊天。

在服务器应用程序中,我有一个主类,只要客户端连接到服务器,它就会创建一个不同的线程。所以,基本上我继续打开一个TCP连接,每个客户端在一个单独的线程上运行。

我遇到发送邮件的问题。当用户向服务器发送新消息+目的地时,服务器必须找到与目标用户有连接的线程并将该消息发送给他。我该怎么做呢。我已将每个线程与用户对象相关联,因此我需要执行类似findThreadByUser(user)的操作,并在获取引用后调用发送消息的方法。我该怎么做?

以下是实现Runnable的ConnectionHandler类的一部分。我想访问该类的特定实例,更具体地说,访问它的末尾方法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);
}

}

3 个答案:

答案 0 :(得分:2)

将客户端对象存储在HashMapUserName(这将是唯一的)作为密钥,并将与之关联的线程作为值...“

答案 1 :(得分:1)

答案 2 :(得分:-1)

为什么不发送广播并让正确的客户接受该消息?