想问一下大家,如何实现聊天室中在线列表实时共享的需求,我真的是看不出代码在哪方面的问题,可能是线程间的同步问题,也不是很懂。
其中多个用户之间的共享聊天室消息均可实现。大致上思路就是服务器端启动之后,每当有个客户端登陆成功之后,就会发送一条登陆信息给服务器,服务器解析之后会广播一条消息给所有的客户端,然后客户端那边接受到这条消息之后就索引数据库,因为在设计数据库的时候,是留了一条属性表示用户是否登陆的。但是就是成功不了,每次都是只有最新登录的页面才显示 的全。
欢迎大家讨论。
想问一下大家,如何实现聊天室中在线列表实时共享的需求,我真的是看不出代码在哪方面的问题,可能是线程间的同步问题,也不是很懂。
欢迎大家讨论。
引自微信小程序:皆我百晓生:
要实现聊天室中在线列表的实时共享,需要对客户端和服务器之间的通信进行处理。以下是一个简单的实现示例:
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);
});
}
}
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();
}
}
以上代码示例中,每当一个客户端连接到服务器时,服务器将创建一个新的线程来处理该客户端的请求。服务器维护一个输出流列表,用于向所有在线用户发送消息和在线用户列表。
在服务器端,当有新的客户端连接或断开连接时,服务器会重新发送在线用户列表给所有在线客户端。
在客户端,当接收到在线用户列表或聊天消息时,客户端会刷新在线用户列表或在聊天框中显示消息。