300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > 韩顺平Java:qq项目离线发送接收消息/文件扩展

韩顺平Java:qq项目离线发送接收消息/文件扩展

时间:2024-03-27 14:29:02

相关推荐

韩顺平Java:qq项目离线发送接收消息/文件扩展

思路:1、在服务端创建一个ConcurrentHashMap线程安全的集合用来存储离线用户的消息和文件,为了实现每个用户可以保存多条离线消息,我们在键值对value中采用ArrayList来保存多条message消息。

//存放离线留言/文件的集合private static ConcurrentHashMap<String, ArrayList<Message>> offLineDb = new ConcurrentHashMap<>();

2、创建ArrayList集合,每个集合对应一个用户,有多少用户就创建多少个集合

public class ManageClientThreads {//创建存储不在线用户文件/消息内容的ArrayList<Message> 集合private static ArrayList<Message> arrayList1 = new ArrayList<>();private static ArrayList<Message> arrayList2 = new ArrayList<>();private static ArrayList<Message> arrayList3 = new ArrayList<>();private static ArrayList<Message> arrayList4 = new ArrayList<>();private static ArrayList<Message> arrayList5 = new ArrayList<>();private static ArrayList<Message> arrayList6 = new ArrayList<>();}

3、 编写一个添加内容的方法,实现把用户对应的message数据存储到ConcurrentHashMap集合中

//添加方法public static void addClientOffLineDb(String userid,Message message){if (userid.equals("100")) {//如果检测到是100的用户的信息就存在arrayList1中arrayList1.add(message);//把message添加到对应的集合中offLineDb.put(userid,arrayList1);//添加内容到集合中}else if (userid.equals("200")){arrayList2.add(message);//把message添加到对应的集合中offLineDb.put(userid,arrayList2);//添加内容到集合中}else if (userid.equals("300")){arrayList3.add(message);//把message添加到对应的集合中offLineDb.put(userid,arrayList3);//添加内容到集合中}else if (userid.equals("至尊宝")){arrayList4.add(message);//把message添加到对应的集合中offLineDb.put(userid,arrayList4);//添加内容到集合中} else if (userid.equals("紫霞仙子")) {arrayList5.add(message);//把message添加到对应的集合中offLineDb.put(userid,arrayList5);//添加内容到集合中}else if (userid.equals("菩提老祖")){arrayList6.add(message);//把message添加到对应的集合中offLineDb.put(userid,arrayList6);//添加内容到集合中}}

4、如果用户不在线我们就调用添加方法,把信息存入集合中

else if (message.getMesType().equals(MessageType.MESSAGE_FILE_MES)){//MessageType.MESSAGE_FILE_MES 文件消息(发送文件)类型//根据message获取getter id,然后在得到对应线程ServerConnectClientThread serverConnectClientThread =ManageClientThreads.getServerConnectClientThread(message.getGetter());if (serverConnectClientThread == null) {//如果用户不在线System.out.println("用户不在线,文件消息存到了offLineDb集合中");//调用方法把message内容存到数组中ManageClientThreads.addClientOffLineDb(message.getGetter(),message);} else {System.out.println("用户在线文件直接转发");//根据getter id 获取到对应的线程,将message对象转发//代码解读:从管理线程的集合中通过message.getGetter()得到对应的线程//在通过线程得到socket,在得到 getOutputStream() 输出流对象,// 最后赋给对象输出流oosObjectOutputStream oos =new ObjectOutputStream(serverConnectClientThread.getSocket().getOutputStream());//得到对应socket的对象输出流,将message对象转发给指定的客户端oos.writeObject(message);}

5、判断存储离线消息的集合中是否有刚刚登录用户的消息如果有就转发给他,并把离线消息从集合中删除。

//查找消息集合中是否有u.getUserId() 对应 Message 内容ArrayList clientOffLineDb = ManageClientThreads.getClientOffLineDb(u.getUserId());if (clientOffLineDb != null){//取出ArrayList数组中的messageIterator<Message> iterator = clientOffLineDb.iterator();//迭代器while (iterator.hasNext()) {Message message1 = iterator.next();//获取对应内容System.out.println(message1);//得到线程对应的输出流 并赋给对象输出流ObjectOutputStream oos1 =new ObjectOutputStream(ManageClientThreads.getServerConnectClientThread(u.getUserId()).getSocket().getOutputStream());oos1.writeObject(message1);//把消息内容回发ManageClientThreads.removeClientOffLineDb(message1.getGetter());//回发成功把消息内容从数组中移除System.out.println("删除了集合中暂存的消息内容");}}

这里只写了扩展离线接收消息/文件的代码,实现了一个用户可以对多个离线用户发送任意数量的离线消息或文件,如果离线用户上线后接收的所有关于该用户的离线文件则会通过服务器转发给他,并从储存离线文件的集合中删除。

通过这种写法的好处是不用修改客户端的代码,只需要在服务器端进行修改,但是不好之处在于代码冗余度过高,如果有更好的思路希望能与大家交流一下。

效果演示:

登录100号用户给200号用户发送离线消息,200号用户登录成功自动读取离线消息并显示

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。