韩顺平多用户即时通信系统控制台版
文章目录
界面

服务端 类图&方法调用图
客户端 类图&方法调用图
功能
登录
客户端
发送User对象
读取从服务器回复的Message对象
如果返回MessageType.MESSAGE_LOGIN_SUCCEED
创建一个线程并启动
根据用户id将线程放入到集合管理
服务端
读取客户端发送的User对象
创建一个Message对象,准备回复客户端
如果验证通过
将message对象回复客户端
创建一个线程,和客户端保持通信,该线程需要持有socket对象
启动该线程
把该线程对象,放入到一个集合中,进行管理
验证不通过则向客户端回复错误类型的message,关闭socket
拉取在线用户
客户端
构建message对象,设置发送者u.getUserId()和消息类型MessageType.MESSAGE_GET_ONLINE_FRIEND
从管理线程的集合中,通过userId,得到这个线程对象
通过这个线程得到关联的socket
得到当前线程的Socket 对应的 ObjectOutputStream对象
向服务器发送消息对象
服务端
如果服务器得到message对象
从ManageClientThreads里取出用户列表
构建消息对象(消息类型,内容,接收者),发送给客户端
无异常退出
客户端解决方法
1.在main线程调用方法,给服务器端发送一个退出系统的message对象
2.调用System.exit(0)//正常退出
服务器端
1.服务器端和某个客户端通信的线程如果接收到了一个退出系统的message后
2.把这个线程持有的socket关闭
3.退出该线程的run方法
私聊
客户端
1.接收用户希望给某个其它在线用户聊天的内容。
2.将消息构建成Messagei对象,通过对应的socket发送给服务器
3.在他的线程(通信线程中),读取到发送的message消息,并显示即可
服务端
1.可以读取到客户端发送给某个客户的消息
2.从管理线程的集合中,根据message对象的getterid获取到对应线程的socket
3.然后将message对象转发给指定客户
群发
客户端
接收要群发的消息
调用一个方法,将消息封装成message对象,发送给服务端
服务端
如果message类型是MessageType.MESSAGE_TO_ALL_MES
从ManageClientThreads取出hashMap
遍历取出在线用户,如果在线用户不等于发送者(排除发消息的这个用户)
就通过onLineUserId取出serverConnectClientThread转发message对象给客户端
发文件
客户端
1.先把文件a.jpg读取到客户端,字节数组
2.把文件对应的字节数组封装到message对象[包含文件内容,sender,getter]
3.将message对象发送给服务端。
服务端
1.接收到message对象
2.拆解message对象的getterid,获取该用户的通信线程
3.把messagei对象转发给指定用户,
服务器推送新闻
服务端
1.推送消息/新闻,本质其实就是群发消息
2.在服务器启动一条独立线程,专门负责发送推送新闻
离线发送文件和消息
服务端
1.当有客户发送消息/文件,如果用户不在线
2.把message存放到服务的db[CHM]
3.key -getterid value->ArrayList
ArrayList存放message
4.当用户登录后,到服务端db去查找,如果有getter=userid,就取出ArrayListl的Message对象,发送给对应客户端即可