首页 > 编程语言 >Java-Day-32( 多用户即时通信系统 —— 文件传输 + 服务器推送新闻 + 离线留言 )

Java-Day-32( 多用户即时通信系统 —— 文件传输 + 服务器推送新闻 + 离线留言 )

时间:2023-07-16 18:00:12浏览次数:34  
标签:文件 Java 文件传输 离线 用户 message 服务端 客户端

Java-Day-32

多用户即时通信系统

文件传输

  • 思路:
    • 客户端里先把文件读取到客户端为字节数组,把文件对应的字节数组封装到 message 对象,内含文件内容、sender、getter,将 message 对象发送给服务端
    • 拆解 message 对象获取 getterid,获取客户端被指定的接收用户的通信线程,把 message 转发给此指定用户
    • 负责接收的客户端获取包含有文件的消息后,将该文件保存到磁盘
  • 客户端 ( 发送方 ):
    • 新建 FileClientService 类用于存放和编写文件相关的服务方法
    • 类中编写方法,存放文件、发送路径、发送者与接收者的 id,要用文件输入流 + 字节数组,将文件存到字节数组中,再将数组存放到 message 中,关闭文件输入流 FileInputStream
    • 最后对象输出流 ObjectOutputStream 将 message 发送给服务端
      • 注意,ObjectOutputStream 不需要关闭流
  • 服务端:
    • ServerConnectClientThread 内 if 语句判断接收 type,如果是文件传输,那就通过 getGetter 获取接收方 socket 的 输出流,发送 message
  • 客户端 ( 接收方 ):
    • ClientConnectServerThread 内 if 语句判断,如果是文件传输,就用文件输出流 FileOutputStream 写入磁盘输出路径,再用 write 方法写读取文件字节数组即可
    • 客户端的控制台显示处不要忘了在正确的 case 处接收键盘输入和调用文件发送的方法

服务器推送新闻

  • 思路:
    • 功能本质就相当于是群发消息
  • 客户端:
    • 可以直接借用群发消息的处理方法
  • 服务端:
    • 新建 SendNewsToAllService 类作为一个线程
    • run 方法直接接收键盘输入,直接设定存储信息类型为群发信息的类型
    • 集合中获取所有在线用户,while 循环获取每一个在线用户的 socket 获取输出流对象于对象输出流
      • 集合.keySet().iterator 迭代器 while 循环 hasNext 遍历,.next 获取所有的用户
    • writeObject ( message )

离线留言

  • 正常发送,在服务端进行方法的编写时,判断如果在线用户的列表里有接收方时才做正常的操作

    • 发现会不太可行
  • 思路:

    • 新开一个集合 ConcurrentHashMap 存放离线 message:getterid:ArrayList< Message >
    • 服务端:
      • 当有客户发送消息或文件,如果用户不在线,就把 message 存放到服务的 db[CHM]
      • key —> getterid,value —> ArrayList,ArrayList 存放 message
      • 当用户登录后,到服务端 db 去查找,如果有 getter=userid,就取出 ArrayList 的 message对象,发送给对应客户端即可
      • 勿忘发送后 remove 离线转上线的用户 id
  • 服务端:

    • 普通信息发送的基础上,判断是否在线,不在线就存储离线线程 ManageOffClientThread 中 ( 内含接收者名为 key,传来的 message 集合为 value )

    • 离线线程里,判断是否存在此 key,若不存在就新建 List 存储,如果存在就 get 获取此 key 下的 List,在其基础上进行新的增加,然后再加入 HashMap 中

    • 注意以下语句是错的,因为第一次存储 iterator 始终都是空的,所以根本不会到 if 判断语句中,更别谈第一次存储了

      while (iterator.hasNext()) {
          String s = iterator.next();
          if (s.equals(userId)) { // hm.get(userId)
          } else {  // new ArrayList<>()  }
      
    • 所以第一次要使用 map 的 containsKey (key1) 方法判断 key1 是否存在,不存在就 new,存在就 get (key2) 获取信息 list.add 进行离线信息的增加与 map.put 的更新

    • 在用户登录成功后调用方法,判断该用户在离线线程集合中是否存在同 key,存在就获取此用户在集合中的离线信息集合,在迭代器循环获取离线信息 List 里的值,拼接所有信息,再携带离线 type 输出流发送给此已经上线的用户,并 remove 此用户的所有离线信息

  • 客户端:

    • 似普通信息的发送,接收为离线消息的 type,String 数组 split 分割后循环显示即可

标签:文件,Java,文件传输,离线,用户,message,服务端,客户端
From: https://www.cnblogs.com/zhu-ya-zhu/p/17558278.html

相关文章

  • Java-JVM-八股文
    线程共享区堆区与方法区是所有线程共享的栈区:主要存放基本数据类型与对象引用(仅限局部变量,成员变量不管是不是基本数据类型都存放于堆)堆区:主要存放对象实例与数组[我的理解就是,由代码操作生成的对象或者说引用类型存放于堆]方法区:类信息(class文件)、静态变量与静态方......
  • 自定义java@注解
    自定义注解主要用于抽象出重复代码,以减少枯燥无味的重复工作量举例:创建Redis分布式锁注解步骤:新建interface接口@Target(ElementType.METHOD)//描述注解使用范围@Retention(RetentionPolicy.RUNTIME)//设置注解时间范围//SOURCE源文件保留//CLASS,......
  • Java-集合-八股文
    list、setlist:有序,可重复,允许多个null,支持下标随机访问set:无序,不可重复,单一null,必须遍历访问arraylist、linkedlistarraylist:基于数组实现,占用连续空间,有利于查找、修改,不利于插入、删除[适用场景不同]linkedlist:基于链表实现,不要求占用空间连续,有利于插入、删除,不利于......
  • Java处理子父级菜单的方式二
    处理存在子父级关系的数据是写代码的过程中常见的操作,前面讲解过使用递归的方法来做,可以参考这篇博客https://www.cnblogs.com/yilangcode/p/16831867.html今天来聊聊一种新的处理方式。使用List集合多轮遍历,添加子父级菜单信息。建表SQLDROPTABLEIFEXISTS`sa_menu`......
  • java序列化和反序列化
    感觉网上很多博客对这个的解释实在太官方了,也没说为什么一定要实现序列化接口。去看看rpc框架源码,或者java网络编程或者向磁盘进行序列化就知道了。首先这是个标记接口,就是用来告诉程序某某对象是可序列化对象,像dubbo框架,要传输对象就必须序列化。网络编程已经告诉你了,想要向另......
  • Java性能优化-测试try-catch放在循环内和外的性能对比与业务区别
    场景Java中使用JMH(JavaMicrobenchmarkHarness微基准测试框架)进行性能测试和优化:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/131723751使用如上方式测试Java中try-catch放在循环内和循环外是否有性能上的差别。注:博客:https://blog.csdn.net/badao_lium......
  • 用java写一个逆置单链表
    用Java写一个逆置单链表单链表是一种常见的数据结构,它由一系列节点组成,每个节点包含一个数据元素和一个指向下一个节点的引用。逆置单链表是指将原来的单链表中的节点顺序颠倒过来。在这篇文章中,我们将使用Java来实现逆置单链表的功能。我们将会介绍单链表的基本概念,并给出逆置单......
  • 用java创建一个单链表
    使用Java可以很方便地创建和操作数据结构,其中包括单链表。单链表是一种常见的线性数据结构,它由一系列节点组成,每个节点包含数据和指向下一个节点的指针。这种数据结构可以用于实现队列、栈、链表等等。在本文中,我们将学习如何使用Java创建一个单链表,并演示一些基本的操作。首先,我......
  • day07 7.1 Java中的面向对象之类与对象
    day077.1Java中的面向对象之类与对象【一】类与对象【1】类定义规范类与对象的关系类是实体对象的概念模型,笼统的,不具体的,比如人类、动物类、鸟类对象又称为实体,类具体化的表现小红/小明小猫一号/小狗一号对象中有属性,有方法不同对象属性是独有的方法是共......
  • JavaScript:将对象数组映射到字典
    JavaScript:将对象数组映射到字典#javascript#打字稿#数据在JavaScript/TypeScript中将对象数组转换为字典的最简单方法:letdata=[{id:1,country:'Germany',population:83623528},{id:2,country:'Austria',population:8975552},{id:3,country......