韩顺平JAVA多用户通讯系统多用户离线留言部分

news/2025/3/15 22:15:38/

思路分析:

1.服务器接收到a用户传递给b用户的message

2.服务器从在线用户列表里面寻找b用户id

3.如果没找到就保存a用户发送来的message,否则就直接发送过去

4.b用户上线发送给服务器一个离线信息请求

5.服务器判断是否有b用户的离线信息
服务器找到b用户的离线信息,就发送过去,服务器没找到就新建一个离线信息类型的message,发送给b用户

6.b用户收到服务器返回的离线信息
如果是正常(私聊,文件)信息就正常显示,如果是离线类型的message就输出一句"没有您的离线信息"

思路分析流程图:

在这里插入图片描述

具体代码

客户端代码

客户端UserClienServuce类里面


public static void Check_for_offline_information(String uid){Message message = new Message();message.setSender(user.getUserId());message.setMessageType(MessageType.MESSAGE_GET_OFFLINE_INFORMATION);//新添加的一个message类型try {ObjectOutputStream oos = new ObjectOutputStream(MangerClientConnectSeverThread.getClientConnectSeverThread(uid).getSocket().getOutputStream());oos.writeObject(message);} catch (IOException e) {e.printStackTrace();}}

调用位置

这里是调用的位置

服务器代码

服务器端代码新建的一个db类


package com.wjh.qqSever.server;import com.wjh.qqcommon.Message;
import com.wjh.qqcommon.MessageType;import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;/*** @author <wjh>* @version:1.0 2023/3/20*/
public class db {private static HashMap<String, List<Message>> offlineusers = new HashMap<>();private static List<Message> offmessage = new ArrayList<Message>();//保存离线用户的messagepublic static saveofflineinformation(String rid, Message message) {if (offlineusers.containsKey(rid)) {offlineusers.get(rid).add(message);} else {List messages = new ArrayList<>();messages.add(message);offlineusers.put(rid, messages);}}/*** 发送服务器存储的该uid的离线信息* 发送之后删除该uid的离线信息*/public static void sendofflinemessages(String uid) {Set<String> keySet = offlineusers.keySet();for (String id :keySet) {if (id.equals(uid)) {try {//取出该uid的list,离线信息有可能是多个.需取出所有messageList<Message> list = getOfflineusers().get(uid);for (int i = 0; i < list.size(); i++) {ObjectOutputStream oos = new ObjectOutputStream(MangeClientThreads.getClientThread(uid).getSocket().getOutputStream());oos.writeObject(list.get(i));}offlineusers.remove(uid);} catch (IOException e) {e.printStackTrace();}}else{Message message = new Message();message.setMessageType(MessageType.MESSAGE_RET_OFFLINE_INFORMATION);try {ObjectOutputStream oos = new ObjectOutputStream(MangeClientThreads.getClientThread(uid).getSocket().getOutputStream());oos.writeObject(message);} catch (IOException e) {e.printStackTrace();}}}}public static HashMap<String, List<Message>> getOfflineusers() {return offlineusers;}}

因为判断接收者是否在线是服务器来判断的,我在SeverConnectClientThread这个类里面进行判断的

package com.wjh.qqSever.server;import com.wjh.qqcommon.Message;
import com.wjh.qqcommon.MessageType;import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.HashMap;
import java.util.List;
import java.util.Set;/*** @author <wjh>* @version:1.0 2023/3/10* 该类是服务器和客户端保持一个通讯*/
public class SeverConnectClientThread extends Thread {private final String id;private final Socket socket;public SeverConnectClientThread(String id, Socket socket) {this.id = id;this.socket = socket;}@Overridepublic void run() {while (true) {try {ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());Message message = (Message) ois.readObject();if (message.getMessageType().equals(MessageType.MESSAGE_GET_ONLINE_FRIEND)) {System.out.println(message.getSender() + "用户需要在线列表菜单");Message message1 = new Message();String onlineFriend = MangeClientThreads.getOnlineFriend();message1.setMessageType(MessageType.MESSAGE_RETURN_ONLINE_FRIEND);message1.setContent(onlineFriend);message1.setReceiver(message.getSender());ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());oos.writeObject(message1);} else if (message.getMessageType().equals(MessageType.MESSAGE_CLIENT_EXIT)) {System.out.println("用户" + message.getSender() + "退出系统");MangeClientThreads.delClientThread(message.getSender());socket.close();break;} else if (message.getMessageType().equals(MessageType.MESSAGE_COMM_MES)) {
//这里判断接收者是否在线,在线就直接发送否则就保存起来SeverConnectClientThread clientThread = MangeClientThreads.getClientThread(message.getReceiver());if (clientThread==null){db.saveofflineinformation(message.getReceiver(),message);}else {ObjectOutputStream oos = new ObjectOutputStream(clientThread.getSocket().getOutputStream());oos.writeObject(message);}} else if (message.getMessageType().equals(MessageType.MESSAGE_MASS_MESSAGEING)) {Set<String> keySet = MangeClientThreads.getHashMap().keySet();for (String id :keySet) {if (!(id.equals(message.getSender()))) //避免发送群聊的用户接受到自己发送的群聊信息{SeverConnectClientThread severConnectClientThread = MangeClientThreads.getHashMap().get(id);ObjectOutputStream oos = new ObjectOutputStream(severConnectClientThread.socket.getOutputStream());oos.writeObject(message);}}} else if (message.getMessageType().equals(MessageType.MESSAGE_FILE)) {//这里判断接收者是否在线,在线就直接发送否则就保存起来SeverConnectClientThread clientThread = MangeClientThreads.getClientThread(message.getReceiver());if (clientThread==null){db.saveofflineinformation(message.getReceiver(),message);}else {try {ObjectOutputStream oos = new ObjectOutputStream(MangeClientThreads.getClientThread(message.getReceiver()).getSocket().getOutputStream());oos.writeObject(message);} catch (IOException e) {e.printStackTrace();}}}//这里接收客户端发送的离线信息请求else if (message.getMessageType().equals(MessageType.MESSAGE_GET_OFFLINE_INFORMATION)){db.sendofflinemessages(message.getSender());}else {System.out.println("其他用户的messa,暂时不处理");}} catch (IOException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();}}}public Socket getSocket() {return socket;}
}

如果我写文章您发现有问题,欢迎积极指出.


http://www.ppmy.cn/news/947686.html

相关文章

QQ在线图片样式 (QQ离线图片变灰,在线时闪动)

风格一 <a targetblank hreftencent://message/?uin你的QQ号码&Site你的博客地址&Menuyes>< img border"0" SRChttp://wpa.qq.com/pa?p1:你的QQ号码:1 alt"点击这里给我发消息"></a> 风格二 <a targetblank hreftencent:…

韩顺平30天javaQQ通信作业扩展-完成离线提醒及接收接收

我这里只显示需要添加的代码&#xff0c;其余代码与韩老师写的一样。 这里用户1发短信给用户2 大体思路&#xff1a;1.在服务器接收用户1输入信息ObjectInputStream的时候有两个分支&#xff08;if-else&#xff09;&#xff0c; 第一&#xff0c;如果在线程池里用户2不存在…

韩顺平QQ项目给离线用户发送信息

在线用户给离线用户发送消息 在下面代码中&#xff0c;仅仅展示私聊时&#xff0c;在线用户给离线用户发送消息&#xff0c;不考虑群发消息或者文件发送。 因为消息的接收者不在线&#xff0c;所以服务端线程集合里&#xff0c;不存在消息接收者的线程。故而这里会爆一个空指针…

安卓实现qq离线图像变灰色或暗色效果

头像由彩色变灰色有两种实现方式&#xff1a; /** 方法1&#xff1a;* ColorMatrix类有一个内置的方法可用于改变饱和度。* 传入一个大于1的数字将增加饱和度&#xff0c;而传入一个0&#xff5e;1之间的数字会减少饱和度。0值将产生一幅灰度图像。*/ColorMatrix matrix new C…

QT之灰色头像(类似QQ离线头像)

QT之灰色头像(类似QQ离线头像) QT之灰色头像类似QQ离线头像 概要效果图上代码下代码结尾 概要 在讲正常图片转灰色图片之前&#xff0c;我们先来了解下灰度图。灰度图又称为灰阶图&#xff0c;任何颜色都由红、绿、蓝三原色组成&#xff0c;假如原来某点的颜色为RGB(R&#xf…

韩顺平老师QQ离线消息

1、Message 类&#xff0c;增加 Arraylise<Message>属性&#xff0c;MessageType 类增加离线消息类型 private ArrayList<Message> arrayList; String MESSAGE_OFFLINE "10";//离线消息类型 2、发送方用户正常发送消息 3、服务器判断接收方用户是否在…

若依vue -【 33 ~ 】

33 登录日志 系统管理 > 日志管理 > 登录日志 1 应用场景 统计用户的活跃度用户错误输入密码多少次 2 后台实现 &#xff08;1&#xff09;SysLoginController#login&#xff1a;登录 /*** 登录方法* * param loginBody 登录信息* return 结果*/PostMapping("/…

golang 日志库zap和日志切割实践

介绍 在许多Go语言项目中&#xff0c;我们需要一个好的日志记录器能够提供下面这些功能&#xff1a; 能够将事件记录到文件中&#xff0c;而不是应用程序控制台。 日志切割-能够根据文件大小、时间或间隔等来切割日志文件。 支持不同的日志级别。例如INFO&#xff0c;DEBUG&a…