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.服务器端

功能实现完毕
day04-1群聊功能的更多相关文章
- Java-->实现群聊功能(C/S模式--TCP协议)
--> Java 对TCP协议的支持: --> java.net包中定义了两个类ServerSocket 和Socket ,分别用来实现双向连接的server 端和client 端. -- ...
- Asp.net SignalR 应用并实现群聊功能 开源代码
ASP.NET SignalR 是为 ASP.NET 开发人员提供的一个库,可以简化开发人员将实时 Web 功能添加到应用程序的过程.实时 Web 功能是指这样一种功能:当所连接的客户端变得可用时服务 ...
- ASP.NET SignalR 与LayIM配合,轻松实现网站客服聊天室(四) 添加表情、群聊功能
休息了两天,还是决定把这个尾巴给收了.本篇是最后一篇,也算是草草收尾吧.今天要加上表情功能和群聊.基本上就差不多了,其他功能,读者可以自行扩展或者优化.至于我写的代码方面,自己也没去重构.好的,我们开 ...
- netty实现群聊功能
[概述] 实现一个网络群聊工具.参与聊天的客户端消息是通过服务端进行广播的. 主要由两块组成:聊天服务器端(ChatServer)和聊天客户端(ChatClient). 聊天服务器(ChatServe ...
- java项目-----客户端与客户端通信--实现群聊功能的代码
这是这个网络聊天室项目的原理图: 很简单,首先ABCD是4个客户端,当A发送信息给服务器,服务器实现以广播的形式把信息全发给每个人---群发群聊 客户端代码: package com.aa; impo ...
- netty无缝切换rabbitmq、activemq、rocketmq实现聊天室单聊、群聊功能
netty的pipeline处理链上的handler:需要IdleStateHandler心跳检测channel是否有效,以及处理登录认证的UserAuthHandler和消息处理MessageHan ...
- Websocket 群聊功能
websocket 群聊 前提关闭防火墙 写入代码 from flask import Flask,request,render_template from geventwebsocket.handl ...
- 基于koa模块和socket.io模块搭建的node服务器实现通过jwt 验证来渲染列表、私聊、群聊功能
1. 具体代码在需要的下载 https://gitee.com/zyqwasd/socket 效果: 2. package.json文件 1. 下载基本的模块 修改了start 脚本 nodemo ...
- Java网络编程Demo,使用TCP 实现简单群聊功能GroupchatSimple,多个客户端输入消息,显示在服务端的控制台
效果: 服务端 客户端 实现代码: 服务端 import java.io.IOException; import java.net.ServerSocket; import java.net.Sock ...
随机推荐
- AI 企业多云存储架构实践 | 深势科技分享
2020 年末,谷歌旗下 DeepMind 研发的 AI 程序 AlphaFold2 在国际蛋白质结构预测竞赛上取得惊人的准确度,使得" AI 预测蛋白质结构"这一领域受到了空前的 ...
- 一个思维导图,带你深入理解 Linux 网络
说明 思维导图 目录 内核接收网络包 内核与用户进程协作 内核发送网络包 TCP 连接 网络性能优化 GitHub 项目 说明 经朋友推荐发现一本好书:<深入理解 Linux 网络>,本文 ...
- vue this.getOptions is not a function
错误提示截图: 问题原因:是由于sass-loader引用的版本过低导致 解决方法:在package.json中增加以下配置后 "sass-loader": "^10&q ...
- Vue生命周期和MVVM框架
生命周期 组件从开始到结束的全过程 创建阶段:beforeCreate.created 挂载阶段:beforeMount.mounted 更新阶段:beforeUpdate.updated 销毁阶段: ...
- CodeQL使用流程
前言 好久没用CodeQL了,看了自己之前写的文章发现竟然没有做过相关记录 然后就不知道怎么用了hhh 使用流程 0x1 生成数据库 我们拿到一套源码,首先需要使用CodeQL生成数据库 执行命令: ...
- kube-scheduler的调度上下文
前一章节了解到了kube-scheduler中的概念,该章节则对调度上下文的源码进行分析 Scheduler Scheduler 是整个 kube-scheduler 的一个 structure,提供 ...
- linux 判断变量是否相等方法
echo $? 输出上一个命令执行成功与否的情况 1表示失败 0 表示成功 test检测文件类型和比较值 有空格时等号才是判断,否则为赋值
- MySQL查询时间常用函数
查看本月数据 SELECT *FROMcontent_publishWHERE date_format(publish_time, '%Y %m') = date_format(DATE_SUB(cu ...
- Hammersley采样类定义和测试
原理参照书籍 类声明: #pragma once #ifndef __HAMMERSLEY_HEADER__ #define __HAMMERSLEY_HEADER__ #include " ...
- CSS(上)
css sprite是什么,有什么优缺点 概念:将多个小图片拼接到⼀个图⽚中.通过 background-position 和元素尺寸调节需要显示的背景图案. 优点: 减少 HTTP 请求数,极⼤地提 ...