将离线文件,离线消息设计为一个离线消息类,实现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 {@Overridepublic 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对应的socketServerConnectClientThread 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头部报错相关,如下:
查找资料,发现同一现象问题解决序列化、反序列化,仅此记录。