思路: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号用户登录成功自动读取离线消息并显示

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

  1. 韩顺平Javaweb:qq项目离线发消息和传输文件的实现

    public class QQServer {private ServerSocket ss=null;//创建一个集合,存放多个用户,如果是这些用户登录就认为是合法的//ConcurrentHash ...

  2. java qq项目_Java版QQ项目

    Java版QQ项目详细设计之:概述 2012-03-16 10:40 wangchangshuai0010 wangchangshuai0010的博客 前两天在博客上,发了一篇博文,概述了java q ...

  3. 韩顺平 java坦克大战_坦克大战完整版(韩顺平java)

    [实例简介] 坦克大战完整源代码(韩顺平java视频配套) [实例截图] [核心代码] 5i86q5 └── 源码 └── Class14 ├── 111.wav ├── bin │   ├── bo ...

  4. ActiveMQ 部署及发送接收消息

    ActiveMQ 部署及发送接收消息 一.           下载 下载地址:http://activemq.apache.org/ 我这里使用的版本为当前最新5.8.0. 下载版本有Windows ...

  5. 【Spring】使用Spring和AMQP发送接收消息(下)

    为什么80%的码农都做不了架构师?>>>    上篇讲了RabbitMQ连接工厂的作用是用来创建RabbitMQ的连接,本篇就来讲讲RabbitMQ的发送消息.通过RabbitMQ发 ...

  6. 韩顺平Java自学笔记 项目 QQ聊天室

    目录 一.项目前的准备 1.为什么选择这个项目 2.项目开发的流程 3.项目的需求 二.开发阶段 1.登录功能实现 2.拉取在线用户实现 3.无异常退出的实现 4.私聊功能的实现 5.群发的实现 6. ...

  7. QQ丐版(韩顺平Java多用户通信项目)

    客户端: package Client; import publi.*; import publi.send_res; import publi.user; import java.io.*; imp ...

  8. 韩顺平老师QQ离线消息

    1.Message 类,增加 Arraylise<Message>属性,MessageType 类增加离线消息类型 private ArrayList<Message> arr ...

  9. 韩顺平Java学习 泛型

    目录 一.泛型的语法 1.传统的方法遍历集合存在的问题 2.使用泛型来解决传统集合添加元素带来的问题 3.泛型使用介绍 4.泛型的使用细节 5.泛型课堂练习 二.自定义泛型 1.自定义泛型类的规范 ​ ...

最新文章

  1. Java项目:仿小米商城系统(前后端分离+java+vue+Springboot+ssm+mysql+maven+redis)
  2. 在webstorm里面添加自定义web browsers的方法
  3. [Java核心技术(卷I)] - vscode手动编译运行继承类
  4. Android 2017-2018面试题详解
  5. unexpected EOF while looking for matching ``‘
  6. WSFC真实场景仲裁处理
  7. springboot怎么杀进程_全新Steam在线游戏 Among us太空狼人杀攻略
  8. IDEA这样配置注释模板,让你高出一个逼格!!
  9. HDU2010 水仙花数【进制】
  10. 368计算机毕业设计
  11. mysql获取当前时间+1天_mysql获取当前时间,前一天,后一天
  12. 燕姿几首歌的歌词-偶得
  13. x轴z轴代表的方向图片_x轴y轴z轴代表的方向_x轴y轴z轴代表的方向图
  14. 解决Could not locate executable null\bin\winutils.exe in the Hadoop binaries
  15. PS如何查看所选图层的实际像素?
  16. 3.27 期货每日早盘操作建议
  17. 计算机通信常用的纠错方式,纠错
  18. webERP 于2011年6月12日发布 4.04.4 版
  19. LCD fb driver for linux 参数计算
  20. 想自学编程,不知道先学哪个?

热门文章

  1. 性能测试工程师技术履历表
  2. ios与android设计适配,IOS与Android UI适配方案
  3. 为玩客云或树莓派安装LNMP和PhpMyAdmin
  4. 计算机水平cet2是什么等级,英语水平CET2是什么意思
  5. Windows10仿mac-os主题
  6. linux内核知识点,linux常见知识点总结
  7. python实现闹钟功能
  8. react-lazyload 源码解析
  9. RTOS环境下低功耗设计思路
  10. 蓝桥杯基础练习~芯片测试FJ的字符串Sine之舞数的读法完美的代价