yi_qiu_ 2023-12-24 17:29 采纳率: 0%
浏览 13
已结题

Java-Swing

想问一下大家,如何实现聊天室中在线列表实时共享的需求,我真的是看不出代码在哪方面的问题,可能是线程间的同步问题,也不是很懂。

img


其中多个用户之间的共享聊天室消息均可实现。大致上思路就是服务器端启动之后,每当有个客户端登陆成功之后,就会发送一条登陆信息给服务器,服务器解析之后会广播一条消息给所有的客户端,然后客户端那边接受到这条消息之后就索引数据库,因为在设计数据库的时候,是留了一条属性表示用户是否登陆的。但是就是成功不了,每次都是只有最新登录的页面才显示 的全。

欢迎大家讨论。

  • 写回答

14条回答 默认 最新

  • 专家-皆知 2023-12-24 17:33
    关注

    引自微信小程序:皆我百晓生

    要实现聊天室中在线列表的实时共享,需要对客户端和服务器之间的通信进行处理。以下是一个简单的实现示例:

    1. 客户端代码:
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.net.Socket;
    import java.util.ArrayList;
    
    public class ChatClient extends JFrame {
        private JTextField messageField;
        private JButton sendButton;
    
        private DefaultListModel<String> onlineListModel;
        private JList<String> onlineList;
        private ArrayList<String> onlineUsers;
    
        private Socket socket;
        private ObjectInputStream inputStream;
        private ObjectOutputStream outputStream;
    
        public ChatClient() {
            // 初始化界面和组件
            // ...
    
            // 创建在线用户列表模型和列表
            onlineListModel = new DefaultListModel<>();
            onlineList = new JList<>(onlineListModel);
            JScrollPane scrollPane = new JScrollPane(onlineList);
            // ...
    
            try {
                // 连接服务器
                socket = new Socket("localhost", 8888);
                outputStream = new ObjectOutputStream(socket.getOutputStream());
                inputStream = new ObjectInputStream(socket.getInputStream());
    
                // 创建一个单独的线程用于接收服务器发送的消息
                Thread receiveThread = new Thread(() -> {
                    try {
                        while (true) {
                            // 接收服务器发送的消息
                            Object obj = inputStream.readObject();
    
                            // 检查消息类型
                            if (obj instanceof ArrayList) { // 在线用户列表
                                onlineUsers = (ArrayList<String>) obj;
                                refreshOnlineList();
                            } else if (obj instanceof String) { // 聊天消息
                                String message = (String) obj;
                                // 在聊天框中显示接收到的消息
                                // ...
                            }
                        }
                    } catch (IOException | ClassNotFoundException e) {
                        e.printStackTrace();
                    }
                });
                receiveThread.start();
            } catch (IOException e) {
                e.printStackTrace();
            }
    
            sendButton.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    String message = messageField.getText();
                    // 发送消息到服务器
                    // ...
                }
            });
        }
    
        private void refreshOnlineList() {
            // 清空在线用户列表
            onlineListModel.clear();
            // 添加新的在线用户
            for (String user : onlineUsers) {
                onlineListModel.addElement(user);
            }
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(() -> {
                ChatClient chatClient = new ChatClient();
                chatClient.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                chatClient.setSize(400, 300);
                chatClient.setVisible(true);
            });
        }
    }
    
    1. 服务器代码:
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.ArrayList;
    
    public class ChatServer {
        private ArrayList<ObjectOutputStream> outputStreams;
    
        public ChatServer() {
            outputStreams = new ArrayList<>();
    
            try {
                ServerSocket serverSocket = new ServerSocket(8888);
                System.out.println("服务器已启动,等待客户端连接...");
    
                while (true) {
                    Socket socket = serverSocket.accept();
                    System.out.println("客户端连接成功:" + socket);
    
                    // 创建一个新的线程处理客户端请求
                    Thread clientThread = new Thread(() -> {
                        try {
                            ObjectInputStream inputStream = new ObjectInputStream(socket.getInputStream());
                            ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream());
    
                            // 将输出流添加到列表中
                            synchronized (outputStreams) {
                                outputStreams.add(outputStream);
                            }
    
                            // 发送在线用户列表给客户端
                            sendOnlineUserList();
    
                            while (true) {
                                // 接收客户端发送的消息
                                Object obj = inputStream.readObject();
    
                                // 检查消息类型
                                if (obj instanceof String) { // 聊天消息
                                    String message = (String) obj;
    
                                    // 转发消息给其他在线用户
                                    synchronized (outputStreams) {
                                        for (ObjectOutputStream os : outputStreams) {
                                            if (os != outputStream) {
                                                os.writeObject(message);
                                                os.flush();
                                            }
                                        }
                                    }
                                }
                            }
                        } catch (IOException | ClassNotFoundException e) {
                            e.printStackTrace();
                        } finally {
                            // 当客户端断开连接时,移除输出流
                            synchronized (outputStreams) {
                                outputStreams.remove(outputStream);
                            }
                            sendOnlineUserList();
                        }
                    });
                    clientThread.start();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        private void sendOnlineUserList() throws IOException {
            // 创建在线用户列表副本
            ArrayList<String> onlineUsers = new ArrayList<>();
            synchronized (outputStreams) {
                for (ObjectOutputStream os : outputStreams) {
                    onlineUsers.add(os.toString());
                }
            }
    
            // 向所有在线用户发送在线用户列表
            synchronized (outputStreams) {
                for (ObjectOutputStream os : outputStreams) {
                    os.writeObject(onlineUsers);
                    os.flush();
                }
            }
        }
    
        public static void main(String[] args) {
            new ChatServer();
        }
    }
    

    以上代码示例中,每当一个客户端连接到服务器时,服务器将创建一个新的线程来处理该客户端的请求。服务器维护一个输出流列表,用于向所有在线用户发送消息和在线用户列表。

    在服务器端,当有新的客户端连接或断开连接时,服务器会重新发送在线用户列表给所有在线客户端。

    在客户端,当接收到在线用户列表或聊天消息时,客户端会刷新在线用户列表或在聊天框中显示消息。

    评论

报告相同问题?

问题事件

  • 系统已结题 1月1日
  • 创建了问题 12月24日

悬赏问题

  • ¥15 Python报错怎么解决
  • ¥15 simulink如何调用DLL文件
  • ¥15 关于用pyqt6的项目开发该怎么把前段后端和业务层分离
  • ¥30 线性代数的问题,我真的忘了线代的知识了
  • ¥15 有谁能够把华为matebook e 高通骁龙850刷成安卓系统,或者安装安卓系统
  • ¥188 需要修改一个工具,懂得汇编的人来。
  • ¥15 livecharts wpf piechart 属性
  • ¥20 数学建模,尽量用matlab回答,论文格式
  • ¥15 昨天挂载了一下u盘,然后拔了
  • ¥30 win from 窗口最大最小化,控件放大缩小,闪烁问题