将离线文件,离线消息设计为一个离线消息类,实现Runnable 接口,具体代码如下
package QQServer.Service;
import qqcommon.Message;
import java.io.File;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @auther SQ
* 实现该线程一直监控 是否有离线文件
* 如果有离线文件,待用户上线的时候,将数据发送给接收方
*/
public class SendOfflineNewsToOne implements Runnable {
@Override
public void run() {
while (true) { // 一直监控离线文件
// 遍历离线信息集合
ConcurrentHashMap<String, ArrayList<Message>> offlineMess = ManageServerConnectClientThreads.getOfflineMess();
Iterator<Map.Entry<String, ArrayList<Message>>> iterator = offlineMess.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, ArrayList<Message>> next = iterator.next();
String receiver = next.getKey();
ArrayList<Message> mess = next.getValue();
int messSize = mess.size();
System.out.println(receiver + "用户离线消息:" + "(" + messSize + "条" + ")");
ObjectOutputStream oos = null;
// 找到receiver对应的socket
ServerConnectClientThread scct = ManageServerConnectClientThreads.getScct(receiver);
// 遍历发送离线消息
for (int i = 0; i < messSize; i++) {
try {
oos = new ObjectOutputStream(scct.getSocket().getOutputStream());
//System.out.println("离线消息" + mess.get(i).toString());
oos.writeObject(mess.get(i));
} catch (IOException e) {
e.printStackTrace();
}
}
// }
ManageServerConnectClientThreads.removeOfflineUser(receiver); // 消息已发送,情况当前用户的离线消息
}
}
}
}
然后在确认登陆之后的代码块中加入调用该类的代码,如下:
// 登陆之后收到离线消息
SendOfflineNewsToOne sendOfflineNewsToOne = new SendOfflineNewsToOne();
new Thread(sendOfflineNewsToOne).start();
遇到问题
在多用户给同一个离线用户发消息时候,能发消息即为在线用户,如:
A > B(离线)发消息 mess1
C > B(离线)发消息 mess2
客户端报错,且返回一条消息,会集合中加入的第一条,与ObjectInputStream头部报错相关,如下:
查找资料,发现同一现象问题解决序列化、反序列化,仅此记录。