IM即时通讯开发在Netty基础上编码实践群聊功能
创始人
2025-05-31 19:58:17
0

群聊的大概流程就是:根据群组 ID 查找到所有的成员集合,然后再遍历找到每个成员对应的连接通道。

群聊通讯流程技术原理如下:

1)群聊和单聊整体上的思路一致:需要保存每个用户和通道的对应关系,方便后期通过用户 ID 去查找到对应的通道,再跟进通道推送消息;2)群聊把消息发送给群员的原理:其实很简单,服务端再保存另外一份映射关系,那就是聊天室和成员的映射关系。发送消息时,首先根据聊天室 ID 找到对应的所有成员,然后再跟进各个成员的 ID 去查找到对应的通道,最后由每个通道进行消息的发送;3)群成员加入某个群聊聊的时候:往映射表新增一条记录,如果成员退群的时候则删除对应的映射记录。

服务端实体

服务端映射关系的管理,分别是:

1)登录信息(用户 ID 和通道);2)群组信息(群组 ID 和群组成员关系)。

主要通过两个 Map 去维护,具体如下:

public class ServerChatGroupHandler extends ChannelInboundHandlerAdapter {

private static Map map=new HashMap();

private static Map groups=new HashMap();

}

//组和成员列表关系实体

@Data

public class Group implements Serializable {

private String groupName;

private List members=new ArrayList();

}

//成员和连接通道的关系实体

public class GroupMember implements Serializable {

private Integer userid;

private Channel channel;

}

我们准备好相应的实体,以及实体和指令的映射关系,具体如下所示:

private static Map> map=new HashMap>();

static{

//登录的请求和响应实体

map.put(1, LoginReqBean.class);

map.put(2, LoginResBean.class);

//创建群组的请求和响应实体

map.put(3, GroupCreateReqBean.class);

map.put(4, GroupCreateResBean.class);

//查看群组的请求和响应实体

map.put(5, GroupListReqBean.class);

map.put(6, GroupListResBean.class);

//加入群组的请求和响应实体

map.put(7,GroupAddReqBean.class);

map.put(8,GroupAddResBean.class);

//退出群组的请求和响应实体

map.put(9,GroupQuitReqBean.class);

map.put(10,GroupQuitResBean.class);

//查看成员列表的请求和响应实体

map.put(11,GroupMemberReqBean.class);

map.put(12,GroupMemberResBean.class);

//发送响应的实体(发送消息、发送响应、接受消息)

map.put(13,GroupSendMsgReqBean.class);

map.put(14,GroupSendMsgResBean.class);

map.put(15,GroupRecMsgBean.class);

}

IM群聊功能的实现,我们需要两个两个业务 Handler:

1)分别是客户端(ClientChatGroupHandler);2)服务端(ServerChatGroupHandler)。

客户端 Handler

客户端 Handler,主要是通过判断实体类型来做不同的业务操作,当然也可以使用 SimpleChannelInboundHandler 去进行 Handler 拆分。即时通讯聊天软件app开发可以加小蓝豆的v:weikeyun24咨询

public class ClientChatGroupHandler extends ChannelInboundHandlerAdapter {

@Override

public void channelActive(ChannelHandlerContext ctx) throws Exception {

//在链接就绪时登录

login(ctx.channel());

}

//主要是“接受服务端”的响应信息

@Override

public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {

if(msg instanceof LoginResBean){

LoginResBean res=(LoginResBean) msg;

System.out.println("登录响应:"+res.getMsg());

if(res.getStatus()==0){

//登录成功

//1.给通道绑定身份

ctx.channel().attr(AttributeKey.valueOf("userid")).set(res.getUserid());

//2.显示操作类型【请看下面】

deal(ctx.channel());

}else{

//登录失败,继续登录

login(ctx.channel());

}

}else if(msg instanceof GroupCreateResBean){

GroupCreateResBean res=(GroupCreateResBean)msg;

System.out.println("创建响应群组:"+res.getMsg());

}else if(msg instanceofGroupListResBean){

GroupListResBean res=(GroupListResBean)msg;

System.out.println("查看群组列表:"+res.getLists());

}elseif(msg instanceofGroupAddResBean){

GroupAddResBean res=(GroupAddResBean)msg;

System.out.println("加入群组响应:"+res.getMsg());

}elseif(msg instanceof GroupQuitResBean){

GroupQuitResBean res=(GroupQuitResBean)msg;

System.out.println("退群群组响应:"+res.getMsg());

}else if(msg instanceof GroupMemberResBean){

GroupMemberResBean res=(GroupMemberResBean)msg;

if(res.getCode()==1){

System.out.println("查看成员列表:"+res.getMsg());

}else{

System.out.println("查看成员列表:"+res.getLists());

}

}else if(msg instanceof GroupSendMsgResBean){

GroupSendMsgResBean res=(GroupSendMsgResBean)msg;

System.out.println("群发消息响应:"+res.getMsg());

}else if(msg instanceof GroupRecMsgBean){

GroupRecMsgBean res=(GroupRecMsgBean)msg;

System.out.println("收到消息fromuserid="+

res.getFromuserid()+

",msg="+res.getMsg());

}

}

}

通过子线程循环向输出控制台输出操作类型的方法,以下方法目前都是空方法,下面将详细讲解。

private void deal(final Channel channel){

final Scanner scanner=new Scanner(http://System.in);

new Thread(new Runnable() {

public void run() {

while(true){

System.out.println("请选择类型:0创建群组,1查看群组,2加入群组,3退出群组,4查看群成员,5群发消息");

int type=scanner.nextInt();

switch(type){

case 0:

createGroup(scanner,channel);

break;

case 1:

listGroup(scanner,channel);

break;

case 2:

addGroup(scanner,channel);

break;

case 3:

quitGroup(scanner,channel);

break;

case 4:

listMembers(scanner,channel);

break;

case 5:

sendMsgToGroup(scanner,channel);

break;

default:

System.out.println("输入的类型不存在!");

}

}

}

}).start();

}

相关内容

热门资讯

原创 控... 对于现代人而言,“白米饭”已经成为了餐桌上的常客,软糯香醇,搭配下饭的小菜,简直美味的不能再美味了。...
原创 蒸... #蒸米饭时,大米下锅前还需多加这一步,否则米饭不香! 在平凡的生活中,一碗好米饭承载着家的味道与温...
摸着肚子像冰块?5道“火炉菜”... 夏天抱着冰西瓜吹空调,结果肚子凉得像冷藏室?喝口冰奶茶,胃里直接开启"震动模式"?别急着翻秋裤,这5...
原创 腌... **《腌带鱼时,别只会加料酒!多加一点“它”,鲜香肉嫩无腥味》** 在美食的世界里,带鱼以其独特的...
原创 经... #经典名菜京酱肉丝,超高颜值,酱香浓郁,口感丝滑 在中华美食的璀璨星河中,京酱肉丝宛如一颗闪耀的明...
新疆伊犁四大草原:每一片都藏着... 新疆伊犁被誉为"塞外江南",这里的草原风光堪称中国最美。伊犁河谷孕育了四大著名草原,每一片都有独特的...
去内江旅游 到自贡吃饭 萝卜白菜,各有所爱。2025年5月11日下午,孩子们自驾车带我与老伴去内江市旅游,到该吃晚饭的时候 ...
四川九寨沟峨眉山旅游跟团5天4... 探秘四川:九寨沟与峨眉山的五日奇幻之旅 四川旅游推荐!当地导游-乐乐:185 8335 5758(加...
四川九寨沟峨眉山旅游参团游5天... 标题:《亲测四川九寨沟峨眉山五日游,花费与美景齐飞,乐乐导游带你玩转天府之国》 四川旅游推荐!当地导...
四川九寨沟都江堰旅游团建五日游... 标题:《四川九寨沟都江堰五日游记:乐乐导游带我领略蜀地风情》 四川旅游推荐!当地导游-乐乐:185 ...
广州市儿童公园“六一”变身欢乐... 粤港澳大湾区首次由智慧人形机器人参与的火炬传递 受访单位供图 羊城晚报记者 孙牧 实习生...
上海警方通报“迪士尼打架事件”... 上海警方通报。 据上海市公安局浦东分局官方微博消息,2025年5月31日18时许,浦东公安分局接报警...
新疆四日游参加旅行团价格,新疆... 新疆四日游参加旅行团价格,新疆旅游四天三夜旅游费用 新疆,这片广袤无垠的西北大地,是东西方文明交流的...
光明日报:民俗体验游火爆,看到... 与五一和国庆相比,这个端午节更像是一个“加长版周末”,很多人选择“周边游”“奔县游”来完成这三天的微...
原创 史... #史无前例!你家是如何处理过年剩菜剩饭的? 新春佳节,阖家团圆,丰盛的菜肴摆满餐桌,欢声笑语中,年...
原创 饺... 大家好呀,我是王大妈,一个天天和厨房打交道的普通主妇。今天要跟大家分享一个我家闺女最近超迷的吃法——...
原创 腐... #腐竹泡发后不“劲道”?酒店厨师教你一招,保证腐竹又软又入味 在美食的世界里,腐竹是一种常见且备受...
原创 胡... #胡萝卜也有新吃法,不炒不煮不红烧,简单搅拌一下,孩子可爱吃了 在寻常的餐桌上,胡萝卜总是以熟悉的...
坚持早上喝一周山药小米糊,胃里... #图文打卡计划#你们有没有过这种感觉?早上起床,胃里像揣了个没精打采的小气球,说不上疼,就是隐隐约约...