day04-1群聊功能
多用户即时通讯系统04
4.编码实现03
4.5功能实现-群聊功能实现
4.5.1思路分析
群聊的实现思路和私聊的实现非常类似。
不同的是:私聊时,服务端接收到消息后,只需要找出接收方的socket并发送消息即可
群聊时,服务端在接收到消息后需要遍历集合中所有的线程,找出除了发送方的所有客户端的socket,并发送消息
群聊思路:
- 客户端 - 发送者:
- 用户在控制台输入信息,客户端接收内容
- 将消息构建成Messgae对象,通过对应的socket发送给服务器
- 服务器:
- 读取客户端(发送者)发送给所有用户(接收者)的消息
- 从管理线程的集合中,遍历所有线程,获取所有socket(除了发送者本身)
- 将Message对象转发给所有的接收者
- 客户端 - 所有接收者:
- 所有接受者分别在线程(通信线程)中,读取到发送者的message消息,并显示即可
4.5.2代码实现
1.客户端:
1.修改MessageType接口
在接口中增加新的消息类型
String MESSAGE_TO_ALL_MES = "7";//表示群发消息包
2.修改MessageClientService类
在该类中增加sendMessageToAll方法,实现群发功能
/** * 群发消息功能 * @param content 内容 * @param senderId 发送者 */ public void sendMessageToAll(String content,String senderId){ //构建 message Message message = new Message(); message.setMesType(MessageType.MESSAGE_TO_ALL_MES);//设置消息类型是群发消息 message.setSender(senderId); message.setContent(content); message.setSendTime(new Date().toString());//发送时间也封装到 message对象中 System.out.println(senderId + " 对大家说 " + content); //发送给服务端 try {//在管理线程的集合中,通过userId来获取线程,通过线程来获取对应的socket,再通过socket获取输出流 ObjectOutputStream oos = new ObjectOutputStream(ManageClientConnectServerThread.getClientConnectServerThread(senderId).getSocket().getOutputStream()); oos.writeObject(message); } catch (IOException e) { e.printStackTrace(); } }
3.修改ClientConnectServerThread类
在该类的run方法中增加新的逻辑业务,增加接收群发消息类型的判断,并在控制台显示
else if (message.getMesType().equals(MessageType.MESSAGE_TO_ALL_MES)) { //接收到的是群发的消息 //就把服务器转发的消息,显示到控制台即可 System.out.println("\n" + message.getSendTime() + "\n" + message.getSender() + " 对大家说: " + "\n" + message.getContent()); }
4.修改QQView类
在该类的内层循环中,调用群发功能的方法:
case "2": System.out.println("请输入想对大家说的话"); String s = Utility.readString(100); //调用一个方法,将消息封装成 message对象,发给服务端 messageClientService.sendMessageToAll(s,userId); break;
2.服务端:
1.修改MessageType接口
在接口中增加新的消息类型
String MESSAGE_TO_ALL_MES = "7";//表示群发消息包
2.修改ServerConnectClientThread类
在该类中增加新的业务逻辑
else if (message.getMesType().equals(MessageType.MESSAGE_TO_ALL_MES)) { //业务四:客户请求群发消息需要遍历管理线程的集合,把所有线程的socket都得到,然后将 message进行转发即可 //得到hm HashMap<String, ServerConnectClientThread> hm = ManageClientThreads.getHm(); //遍历 Iterator<String> iterator = hm.keySet().iterator(); while (iterator.hasNext()) { //取出所有userId String onlineUserId = iterator.next().toString(); //取出除了发送者的所有用户id if (!onlineUserId.equals(message.getSender())) { //转发message //从集合中取出线程,在线程中取出socket,根据socket获得输出流,将socket的输出流转化为对象输出流 ObjectOutputStream oos = new ObjectOutputStream(hm.get(onlineUserId).getSocket().getOutputStream()); oos.writeObject(message); } } }
3.修改ManageClientThreads类
在该类中增加方法,获取集合
//返回hashmap public static HashMap<String ,ServerConnectClientThread> getHm(){ return hm; }
运行程序:
1.运行服务端,进行监听

2.运行三个客户端,登录三个用户

3.在 用户uid=100 的账号发送群发消息

4.其他用户也接收到了消息


5.服务器端

功能实现完毕
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!