day03-3私聊功能
2023-03-31 10:46:18 时间
多用户即时通讯系统03
4.编码实现02
4.4功能实现-私聊功能实现
4.4.1思路分析
- 客户端 - 发送者:
- 用户在控制台输入信息,客户端接收内容
- 将消息构建成Messgae对象,通过对应的socket发送给服务器
- 服务器:
- 可以读取到客户端(发送者)发送给某个用户(接收者)的消息
- 从管理线程的集合中,根据messgae对象的信息,获取到接收者的userId,从而获取接收者的socket
- 最后将Message对象转发给指定客户(接收者)
- 客户端 - 接收者:
- 在接收者的线程(通信线程中),读取到发送者的message消息,并显示即可
4.4.2代码实现
1.客户端
1.MessageClientService类
这里新建一个类,专门用来管理聊天(私聊/群聊)的功能
package qqclient.service;
import qqcommon.Message;
import qqcommon.MessageType;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.Date;
/**
* @author 李
* @version 1.0
* 该类提供和消息(私聊、群聊)相关的服务方法
*/
public class MessageClientService {
/**
* @param content 内容
* @param senderId 发送用户id
* @param getterId 接收用户id
*/
public void sendMessageToOne(String content, String senderId, String getterId) {
//构建 message
Message message = new Message();
message.setMesType(MessageType.MESSAGE_COMM_MES);//设置消息类型是普通的聊天类型
message.setSender(senderId);
message.setGetter(getterId);
message.setContent(content);
message.setSendTime(new Date().toString());//发送时间也封装到message对象中
System.out.println(senderId + " 对 " + getterId + " 说 " + content);
//发送给服务端
try {//在管理线程的集合中,通过userId来获取线程,通过线程来获取对应的socket,再通过socket获取输出流
ObjectOutputStream oos =
new ObjectOutputStream(ManageClientConnectServerThread.getClientConnectServerThread(senderId).getSocket().getOutputStream());
oos.writeObject(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
2.修改:ClientConnectServerThread类
在该类的run方法中修改业务代码,增加else if语句
else if (message.getMesType().equals(MessageType.MESSAGE_COMM_MES)) {
//接收到的是普通的聊天消息
//就把服务器转发的消息,显示到控制台即可
System.out.println(message.getSendTime() + "
" + message.getSender()
+ " 对" + message.getGetter() + " 说" + message.getContent());
}
![image-20220922220740157](https://liyuelian.oss-cn-shenzhen.aliyuncs.com/imgs/image-20220922220740157.png)
3.修改处:QQView类
- 在类中增加属性messageClientService
private MessageClientService messageClientService = new MessageClientService();//该对象用于私聊/群聊
- 在类中的内层循环中调用messageClientService对象中的方法
![image-20220922221128611](https://liyuelian.oss-cn-shenzhen.aliyuncs.com/imgs/image-20220922221128611.png)
case "3":
System.out.println("请输入想聊天的用户号(在线):");
String getterId = Utility.readString(50);
System.out.println("请输入想说的话:(100个字符以内)");
String content = Utility.readString(100);
//编写一个方法,将消息发送给服务端
messageClientService.sendMessageToOne(content,userId,getterId);
break;
2.服务端:
1.修改:ServerConnectClientThread类
- 在该类中增加方法getSocket()
public Socket getSocket() {
return socket;
}
- 在该类中的run方法中增加私聊的业务代码
else if (message.getMesType().equals(MessageType.MESSAGE_COMM_MES)) {
//业务三:客户请求和某用户私聊
//根据message获取getterId,再得到接收者对应的线程
ServerConnectClientThread serverConnectClientThread =
ManageClientThreads.getServerConnectClientThread(message.getGetter());
//得到对应的socket的输出流,将message转发给指定的用户
ObjectOutputStream oos =
new ObjectOutputStream(serverConnectClientThread.getSocket().getOutputStream());
oos.writeObject(message);//转发消息,提示:如果客户不在线,可以保存消息到数据库,实现离线留言
}
运行:
![image-20220922215217273](https://liyuelian.oss-cn-shenzhen.aliyuncs.com/imgs/image-20220922215217273.png)
2.客户端:登录三个用户菩提老祖、至尊宝、紫霞仙子,使其相互通信:
用户1:
![image-20220922215310105](https://liyuelian.oss-cn-shenzhen.aliyuncs.com/imgs/image-20220922215310105.png)
用户2:
![image-20220922215516367](https://liyuelian.oss-cn-shenzhen.aliyuncs.com/imgs/image-20220922215516367.png)
用户3:
相关文章
- 金融服务领域的大数据:即时分析
- 影响大数据、机器学习和人工智能未来发展的8个因素
- 从0开始构建一个属于你自己的PHP框架
- 如何将Hadoop集成到工作流程中?这6个优秀实践必看
- SEO公司使用大数据优化其模型的5种方法
- 关于Web Workers你需要了解的七件事
- 深入理解HTTPS原理、过程与实践
- 增强分析:数据和分析的未来
- PHP协程实现过程详解
- AI专家:大数据知识图谱——实战经验总结
- 关于PHP的错误机制总结
- 利用数据分析量化协同过滤算法的两大常见难题
- 怎么做大数据工作流调度系统?大厂架构师一语点破!
- 2019大数据处理必备的十大工具,从Linux到架构师必修
- OpenCV中的KMeans算法介绍与应用
- 教大家如果搭建一套phpstorm+wamp+xdebug调试PHP的环境
- CentOS下三种PHP拓展安装方法
- Go语言HTTP Server源码分析
- Go语言HTTP Server源码分析
- 2017年4月编程语言排行榜:Hack首次进入前五十