多用户即时通讯系统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群聊功能的更多相关文章

  1. Java-->实现群聊功能(C/S模式--TCP协议)

    --> Java 对TCP协议的支持: --> java.net包中定义了两个类ServerSocket 和Socket ,分别用来实现双向连接的server 端和client 端. -- ...

  2. Asp.net SignalR 应用并实现群聊功能 开源代码

    ASP.NET SignalR 是为 ASP.NET 开发人员提供的一个库,可以简化开发人员将实时 Web 功能添加到应用程序的过程.实时 Web 功能是指这样一种功能:当所连接的客户端变得可用时服务 ...

  3. ASP.NET SignalR 与LayIM配合,轻松实现网站客服聊天室(四) 添加表情、群聊功能

    休息了两天,还是决定把这个尾巴给收了.本篇是最后一篇,也算是草草收尾吧.今天要加上表情功能和群聊.基本上就差不多了,其他功能,读者可以自行扩展或者优化.至于我写的代码方面,自己也没去重构.好的,我们开 ...

  4. netty实现群聊功能

    [概述] 实现一个网络群聊工具.参与聊天的客户端消息是通过服务端进行广播的. 主要由两块组成:聊天服务器端(ChatServer)和聊天客户端(ChatClient). 聊天服务器(ChatServe ...

  5. java项目-----客户端与客户端通信--实现群聊功能的代码

    这是这个网络聊天室项目的原理图: 很简单,首先ABCD是4个客户端,当A发送信息给服务器,服务器实现以广播的形式把信息全发给每个人---群发群聊 客户端代码: package com.aa; impo ...

  6. netty无缝切换rabbitmq、activemq、rocketmq实现聊天室单聊、群聊功能

    netty的pipeline处理链上的handler:需要IdleStateHandler心跳检测channel是否有效,以及处理登录认证的UserAuthHandler和消息处理MessageHan ...

  7. Websocket 群聊功能

    websocket 群聊 前提关闭防火墙 写入代码 from flask import Flask,request,render_template from geventwebsocket.handl ...

  8. 基于koa模块和socket.io模块搭建的node服务器实现通过jwt 验证来渲染列表、私聊、群聊功能

    1. 具体代码在需要的下载 https://gitee.com/zyqwasd/socket 效果: 2. package.json文件 1. 下载基本的模块  修改了start 脚本  nodemo ...

  9. Java网络编程Demo,使用TCP 实现简单群聊功能GroupchatSimple,多个客户端输入消息,显示在服务端的控制台

    效果: 服务端 客户端 实现代码: 服务端 import java.io.IOException; import java.net.ServerSocket; import java.net.Sock ...

随机推荐

  1. # Vue3 setup 函数

    Vue3 setup 函数 vue2 和 vue3 开发的区别 首先,目前来说 vue3 发布已经有一段时间了,但是呢,由于还处于优化完善阶段,对于 vue3 开发项目的需求不是很高,主要还是以 vu ...

  2. netty系列之:kequeue传输协议详解

    目录 简介 KQueueEventLoopGroup KQueueEventLoop KQueueServerSocketChannel和KQueueSocketChannel 总结 简介 在前面的章 ...

  3. Unity3D学习笔记6——GPU实例化(1)

    目录 1. 概述 2. 详论 3. 参考 1. 概述 在之前的文章中说到,一种材质对应一次绘制调用的指令.即使是这种情况,两个三维物体使用同一种材质,但它们使用的材质参数不一样,那么最终仍然会造成两次 ...

  4. 关于 用fscanf读文件,把文件中用##分割的内容分开

    今天呀,被学弟问了一个问题 文件里存的是"123##456##0##1644444.....##" 为什么用fscanf(fp, "%s##%s......", ...

  5. c语言编译器介绍

    目录 一.IDE(集成开发环境) 1.windows 编译器 2.Mac中使用 二.环境安装 1.windows安装gcc A.进入安装所在目录,找到MinGW. B.找到我的电脑,右键选择属性. C ...

  6. 边缘计算 KubeEdge+EdgeMash

    简介 KubeEdge是面向边缘计算场景.专为边云协同设计的业界首个云原生边缘计算框架,在 Kubernetes 原生的容器编排调度能力之上实现了边云之间的应用协同.资源协同.数据协同和设备协同等能力 ...

  7. 华为云Stack南向开放框架,帮助生态伙伴高效入云

    摘要:CloudBonder的生态社区通过一系列生态项目,解决提交叉组合.架构分层不清晰.运维界面不清晰等问题,简化对接流程,降低生态伙伴对接成本,缩短对接时间. 本文分享自华为云社区<[华为云 ...

  8. 教你使用CANN将照片一键转换成卡通风格

    摘要:这次是将AnimeGAN部署到Ascend 310,从而实现对自己想要图片的一键转换为我们想看到的卡通风格. 本文分享自华为云社区<[CANN训练营]CANN训练营_昇腾AI趣味应用实现A ...

  9. 基础数学知识 / Math(updating)

    埃氏筛:朴素筛法求素数,o(nloglogn) int prime[N], tot; bool st[N]; // true:not prime, false:is prime void get_pr ...

  10. Apache DolphinScheduler 1.3.6 功能发布说明

    参与人员 @chengshiwen.@hailin0.@wanghong1314.@ruanwenjun.@xxjingcd.@zhangguohao.@zhuangchong.@syb8535531 ...