思路分析:
1.服务器接收到a用户传递给b用户的message
2.服务器从在线用户列表里面寻找b用户id
3.如果没找到就保存a用户发送来的message,否则就直接发送过去
4.b用户上线发送给服务器一个离线信息请求
5.服务器判断是否有b用户的离线信息
服务器找到b用户的离线信息,就发送过去,服务器没找到就新建一个离线信息类型的message,发送给b用户
6.b用户收到服务器返回的离线信息
如果是正常(私聊,文件)信息就正常显示,如果是离线类型的message就输出一句"没有您的离线信息"
思路分析流程图:
具体代码
客户端代码
客户端UserClienServuce类里面
public static void Check_for_offline_information(String uid)
{
Message message = new Message();
message.setSender(user.getUserId());
message.setMessageType(MessageType.MESSAGE_GET_OFFLINE_INFORMATION);//新添加的一个message类型
try {
ObjectOutputStream oos = new ObjectOutputStream(
MangerClientConnectSeverThread.
getClientConnectSeverThread(uid).getSocket().getOutputStream());
oos.writeObject(message);
} catch (IOException e) {
e.printStackTrace();
}
}
调用位置
服务器代码
服务器端代码新建的一个db类
package com.wjh.qqSever.server;
import com.wjh.qqcommon.Message;
import com.wjh.qqcommon.MessageType;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
/**
* @author <wjh>
* @version:1.0 2023/3/20
*/
public class db {
private static HashMap<String, List<Message>> offlineusers = new HashMap<>();
private static List<Message> offmessage = new ArrayList<Message>();
//保存离线用户的message
public static saveofflineinformation(String rid, Message message) {
if (offlineusers.containsKey(rid)) {
offlineusers.get(rid).add(message);
} else {
List messages = new ArrayList<>();
messages.add(message);
offlineusers.put(rid, messages);
}
}
/**
* 发送服务器存储的该uid的离线信息
* 发送之后删除该uid的离线信息
*/
public static void sendofflinemessages(String uid) {
Set<String> keySet = offlineusers.keySet();
for (String id :
keySet) {
if (id.equals(uid)) {
try {
//取出该uid的list,离线信息有可能是多个.需取出所有message
List<Message> list = getOfflineusers().get(uid);
for (int i = 0; i < list.size(); i++) {
ObjectOutputStream oos = new ObjectOutputStream(MangeClientThreads.getClientThread(uid).getSocket().getOutputStream());
oos.writeObject(list.get(i));
}
offlineusers.remove(uid);
} catch (IOException e) {
e.printStackTrace();
}
}
else
{
Message message = new Message();
message.setMessageType(MessageType.MESSAGE_RET_OFFLINE_INFORMATION);
try {
ObjectOutputStream oos = new ObjectOutputStream(MangeClientThreads.getClientThread(uid).getSocket().getOutputStream());
oos.writeObject(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static HashMap<String, List<Message>> getOfflineusers() {
return offlineusers;
}
}
因为判断接收者是否在线是服务器来判断的,我在SeverConnectClientThread这个类里面进行判断的
package com.wjh.qqSever.server;
import com.wjh.qqcommon.Message;
import com.wjh.qqcommon.MessageType;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
/**
* @author <wjh>
* @version:1.0 2023/3/10
* 该类是服务器和客户端保持一个通讯
*/
public class SeverConnectClientThread extends Thread {
private final String id;
private final Socket socket;
public SeverConnectClientThread(String id, Socket socket) {
this.id = id;
this.socket = socket;
}
@Override
public void run() {
while (true) {
try {
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
Message message = (Message) ois.readObject();
if (message.getMessageType().equals(MessageType.MESSAGE_GET_ONLINE_FRIEND)) {
System.out.println(message.getSender() + "用户需要在线列表菜单");
Message message1 = new Message();
String onlineFriend = MangeClientThreads.getOnlineFriend();
message1.setMessageType(MessageType.MESSAGE_RETURN_ONLINE_FRIEND);
message1.setContent(onlineFriend);
message1.setReceiver(message.getSender());
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.writeObject(message1);
} else if (message.getMessageType().equals(MessageType.MESSAGE_CLIENT_EXIT)) {
System.out.println("用户" + message.getSender() + "退出系统");
MangeClientThreads.delClientThread(message.getSender());
socket.close();
break;
} else if (message.getMessageType().equals(MessageType.MESSAGE_COMM_MES)) {
//这里判断接收者是否在线,在线就直接发送否则就保存起来
SeverConnectClientThread clientThread = MangeClientThreads.getClientThread(message.getReceiver());
if (clientThread==null)
{
db.saveofflineinformation(message.getReceiver(),message);
}
else {
ObjectOutputStream oos = new ObjectOutputStream(clientThread.getSocket().getOutputStream());
oos.writeObject(message);
}
} else if (message.getMessageType().equals(MessageType.MESSAGE_MASS_MESSAGEING)) {
Set<String> keySet = MangeClientThreads.getHashMap().keySet();
for (String id :
keySet) {
if (!(id.equals(message.getSender()))) //避免发送群聊的用户接受到自己发送的群聊信息
{
SeverConnectClientThread severConnectClientThread = MangeClientThreads.getHashMap().get(id);
ObjectOutputStream oos = new ObjectOutputStream(severConnectClientThread.socket.getOutputStream());
oos.writeObject(message);
}
}
} else if (message.getMessageType().equals(MessageType.MESSAGE_FILE)) {
//这里判断接收者是否在线,在线就直接发送否则就保存起来
SeverConnectClientThread clientThread = MangeClientThreads.getClientThread(message.getReceiver());
if (clientThread==null)
{
db.saveofflineinformation(message.getReceiver(),message);
}
else {
try {
ObjectOutputStream oos = new ObjectOutputStream(MangeClientThreads.getClientThread(message.getReceiver()).getSocket().getOutputStream());
oos.writeObject(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
//这里接收客户端发送的离线信息请求
else if (message.getMessageType().equals(MessageType.MESSAGE_GET_OFFLINE_INFORMATION))
{
db.sendofflinemessages(message.getSender());
}
else {
System.out.println("其他用户的messa,暂时不处理");
}
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public Socket getSocket() {
return socket;
}
}
如果我写文章您发现有问题,欢迎积极指出.