简体   繁体   English

在java socket编程中管理所有传入的聊天消息

[英]Manage all incoming chat messages in java socket programming

I am developing a program that has a chat feature and I am using sockets in it.我正在开发一个具有聊天功能的程序,我正在其中使用套接字。 In my case, I want to handle each of the client in a different window chat(PLEASE SEE ATTACHED IMAGE).就我而言,我想在不同的窗口聊天中处理每个客户端(请参阅附加图片)。

As of now, when 1 client is connected, there is no problem.截至目前,当连接1个客户端时,没有问题。 But when 2 clients are connected, the first client will be overridden by the 2nd one and he can't receive messages from server not unless I close the connection for the latest client connected(Server still receiving messages from all client although only 1 client can receive from server).但是当连接了 2 个客户端时,第一个客户端将被第二个覆盖,除非我关闭最新连接的客户端的连接,否则他无法从服务器接收消息(服务器仍然接收来自所有客户端的消息,尽管只有 1 个客户端可以从服务器接收)。

How am I gonna do this?我要怎么做? I am using captain casa framework I want to manage it like what did the image below do.我正在使用船长 casa 框架,我想像下图那样管理它。

IMAGE HERE图像在这里

Here is my code: Server:这是我的代码:服务器:

public void mainserver(){
        Thread server = new Thread(new Runnable() {
            @Override
            public void run() {

                try {
                    serverSocket = new ServerSocket(port);
                    System.out.println("Server Online... \nWaiting for Connections");
                } catch (IOException e) {
                    e.printStackTrace();
                }

                while (accept){
                    try {
                        socket = serverSocket.accept();
                        System.out.println("New Connection Estasblished!!!");

                        chatHandler chat = new chatHandler(socket);
                        chat.start();
                    } catch (IOException e) {
                        System.out.println("server not terminate all connections");
                        System.exit(-1);
                    }
                }
            }
        });
        server.start();
    }

public class chatHandler extends Thread{

       Socket socket;

       public chatHandler(Socket socket){
           this.socket = socket;
       }

       public void run(){
           try {
               din = new DataInputStream(socket.getInputStream());
               dout = new DataOutputStream(socket.getOutputStream());

               dout.writeUTF("Hi! Thank you for reaching us! How may I help you!?");

               while (!read.equals(".end")){

                   read = din.readUTF();

                   if (getServerArea()!=null){
                       setServerArea(getServerArea()+"\n"+read);
                   }else {
                       setServerArea(read);
                   }
               }
               System.out.println("end of chat server");
           } catch (IOException e) {
               e.printStackTrace();
           }finally {
               System.out.println("Exit");
               try {
                   dout.close();
                   din.close();
                   socket.close();
               } catch (IOException e) {
                   e.printStackTrace();
               }
           }

       }
   }

public void serverSend(javax.faces.event.ActionEvent event) { // "Send" button
        write = getServerField();
        try {
            dout.writeUTF(write);
            dout.flush();
            if (getServerArea()!=null){
                setServerArea(getServerArea()+"\n"+write);
                setServerField("");
            }else {
                setServerArea(write);
                setServerField("");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println(write);
    }

Client:客户:

public void client(){
        Thread client = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    socket = new Socket("localhost",port);

                    din  = new DataInputStream(socket.getInputStream());
                    dout = new DataOutputStream(socket.getOutputStream());

                    while (!read.equals("bye")){
                        read = din.readUTF();

                        if (getClientArea()!=null){
                            setClientArea(getClientArea()+"\n"+read);
                        }else {
                            setClientArea(read);
                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }finally {
                    try {
                        din.close();
                        dout.close();
                        socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        client.start();
    }

    public void clientSend(javax.faces.event.ActionEvent event) {
        write = getClientField();
        try {
            dout.writeUTF(write);
            dout.flush();
            if (getClientArea()!=null){
                setClientArea(getClientArea()+"\n"+write);
                setClientField("");
            }else {
                setClientArea(write);
                setClientField("");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println(write);
    }

I believe I understand the problem, and how to correct it.我相信我理解这个问题,以及如何纠正它。

You are using a unique thread (chatHandler) for each new connection.您为每个新连接使用唯一的线程 (chatHandler)。
This thread writes an automatic "Hello" upon connection, but thereafter is dedicated to reading messages (in the while loop you only read din) and updating the console accordingly.该线程在连接时自动写入“Hello”,但此后专门用于读取消息(在 while 循环中您只读取 din)并相应地更新控制台。 Since each thread is managing a reference to din, all incoming messages are OK.由于每个线程都在管理对 din 的引用,因此所有传入的消息都可以。

However, it seems that writing back to a client (serverSend) is not in a thread;但是,写回客户端(serverSend)似乎不在线程中; it is triggered by a button event.它由按钮事件触发。 At this point, dout will be a reference to the most recent connection, and not a reference to the client intended to get the message.此时,dout 将是对最近连接的引用,而不是对打算获取消息的客户端的引用。 That is why the most recent client gets all future messages.这就是为什么最近的客户端会收到所有未来的消息。

The correction is to choose the correct 'dout' for the intended client.更正是为目标客户选择正确的“dout”。 When the server 'operator' chooses to write a message back (clicking the send button), somehow you need to obtain the correct 'dout' for that client.当服务器“操作员”选择写回消息(单击发送按钮)时,您需要以某种方式为该客户端获取正确的“dout”。

One way to do this is to establish dout prior to creating the thread (using socket), and maintain a relationship between each client, and it's corresponding dout (ie in a Map).一种方法是在创建线程之前建立dout(使用socket),并维护每个客户端之间的关系,以及它对应的dout(即在Map中)。

If the problem is still not clear (that each client must have a unique reference to dout), please let me know and I will try to clarify.如果问题仍然不明确(每个客户必须有一个唯一的 Dout 引用),请告诉我,我会尽力澄清。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM