java实现多用户即时通信系统(二)——离线留言和离线发送文件

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


概述

这里就不过多赘述,实现了离线留言和离线文件两个功能,这两个相当于扩展功能。
方法很多,我这边分享一下我的方法。
优点在于,只需要在 QQServer类 和 ServerConnectClientThread类 中增加代码
可以存储多条message和文件
当然,如果可以用mysql肯定最好还是用mysql


QQServerRewrite项目

QQServer类

private static ConcurrentHashMap<String, ArrayList<Message>> offlineDb = new ConcurrentHashMap<>();//存放离线消息
    private static ConcurrentHashMap<String, ArrayList<Message>> offlineFiles = new ConcurrentHashMap<>();//存放离线文件
    

在这里插入图片描述

QQServer构造器/构造方法中

//当离线用户登录时,就将存储在offlineDb中的消息,发送到对应的客户端
                    ConcurrentHashMap.KeySetView<String, ArrayList<Message>> keys = offlineDb.keySet();
                    //遍历 keys
                    for (String key : keys) {
                        if (user.getUserId().equals(key)) {//此处判断,现在登录成功的用户,是否有离线留言
                            ArrayList<Message> messages = offlineDb.get(key);//取出 该用户对应的 message集合
                            //遍历messages
                            for (Message offlineMessage : messages) {
                                //创建对应的对象输出流
                                ObjectOutputStream oos2 =
                                        new ObjectOutputStream(ManageClientThreads.getServerConnectClientThread(key)
                                                .getSocket().getOutputStream());
                                //发送 offlineMessage
                                oos2.writeObject(offlineMessage);
                            }
                            //遍历该用户的messages后,就将它从 offlineDb中移除
                            offlineDb.remove(key);
                        }
                    }

                    //同时,让离线缓存的文件也传输到 客户端的程序上
                    ConcurrentHashMap.KeySetView<String, ArrayList<Message>> keys2 = offlineFiles.keySet();
                    //遍历 keySet
                    for (String key : keys2) {
                        if (user.getUserId().equals(key)) {
                            ArrayList<Message> messages = offlineFiles.get(key);
                            for (Message offlineMessage : messages) {
                                ObjectOutputStream oos2 =
                                        new ObjectOutputStream(ManageClientThreads.getServerConnectClientThread(key).getSocket().getOutputStream());
                                oos2.writeObject(offlineMessage);
                            }
                            //遍历后,从集合中移除
                            offlineFiles.remove(key);
                        }
                    }

QQServer中添加两个静态方法

/**
     * 将message对象,存入到 offlineDb中
     * @param getter 接收者
     * @param message Message对象
     */
    public static void addOfflineMessage(String getter, Message message) {
        if (!offlineDb.containsKey(getter)) {//当offlineDb中没有保存过 key为的getter的数据时
            ArrayList<Message> messages = new ArrayList<>();
            messages.add(message);
            offlineDb.put(getter, messages);
        } else {
            ArrayList<Message> messages = offlineDb.get(getter);
            messages.add(message);
        }
    }

    /**
     * 根据 接收的客户端的id,将 id-message 存入到 offlineFile中
     * @param getter 接收者id
     * @param message 带有文件的字节数组的,离线消息
     */
    public static void addOfflineFile(String getter, Message message) {
        if (!offlineFiles.containsKey(getter)) {//如果之前没有储存过 该用户的离线文件
            ArrayList<Message> messages = new ArrayList<>();
            messages.add(message);
            offlineFiles.put(getter, messages);
        } else {//之前存储过,就在原先基础上进行添加
            ArrayList<Message> messages = offlineFiles.get(getter);
            messages.add(message);
        }
    }

ServerConnectClientThread类

这里需要做一些小小的修改,不只是单纯添加
1.

else if (message.getMessageType().equals(MessageType.MESSAGE_COMM_MES)) {//客户端要私聊
                    //将接收到的 message转发给 客户端
                    //获取 getter对应的线程
                    ServerConnectClientThread serverConnectClientThread = ManageClientThreads.getServerConnectClientThread(message.getGetter());

                    //判断接收消息的用户是否在线
                    if (serverConnectClientThread == null) {//用户不在线就将消息缓存在服务端
                        //这里我们在QQServer编写一个方法,将message 存入到 offlineDb集合中
                        QQServer.addOfflineMessage(message.getGetter(), message);
                    } else {//用户在线就正常发送消息
                        //获取 该线程对应的对象输出流,并将消息转发给客户端
                        ObjectOutputStream oos =
                                new ObjectOutputStream(serverConnectClientThread.getSocket().getOutputStream());
                        oos.writeObject(message);
                    }
                }
else if (message.getMessageType().equals(MessageType.MESSAGE_FILE_MES)) {//客户端要发送文件
                    //获取对应的线程
                    ServerConnectClientThread serverConnectClientThread =
                            ManageClientThreads.getServerConnectClientThread(message.getGetter());

                    //在这里加入对离线文件的处理
                    if (serverConnectClientThread == null) {//如果用户离线,就将 message对象存入到 offlineFiles中
                        QQServer.addOfflineFile(message.getGetter(), message);
                    } else {
                        //获取该线程对应的对象输出流,将message转发给接收消息的客户端
                        ObjectOutputStream oos =
                                new ObjectOutputStream(serverConnectClientThread.getSocket().getOutputStream());
                        oos.writeObject(message);
                    }
                }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值