微信公众号
王皓的GitHub:https://github.com/TenaciousDWang
我们在实现的单聊后,来继续实现群聊功能,今天主要写一下群聊的发起与通知。
我们在上一篇文章中已经介绍过客户端直接互聊的实现,群聊同样需要客户端登陆,并存储登陆信息。我们分别登陆A,B,C三个客户端。
假设A发起A,B,C三人群聊,那么A客户端需要向服务端发送创建群聊请求,数据包内应该附带A,B,C三个人的标识。客户端创建一个专门存储群聊映射的容器,产生一个群聊ID,并绑定这三个人的标识,创建成功后,A发送群聊ID与发送消息到服务端,服务端根据群聊ID去查找群聊对应的人员标识,然后遍历人员标识对应的连接,写入消息,所有客户端接受消息并打印即可。
随着命令越来越多,我们来重构一下控制台程序。首先我们抽象出一个控制台ConsoleCommand接口。
然后我们创建一个ConsoleCommandManager类来实现它,这里面我们定义控制台命令,放到一个容器里,调用时根据不同指令,向连接中写入数据。
接下来我们来举一个控制台命令对象的例子CreateGroupConsoleCommand.java
输入指令后,获取控制台输入信息,处理后放入数据包中,写入连接发送。
接下来我们来看一下客户端的改造,创建两个command对象,一个是管理对象,一个登录对象,如果没有登陆先登录,登陆后使用command管理对象,根据输入不同的指令来执行不同数据包的写入,还是起一个线程监控控制台输入。
这样我们的代码结构更加合理,简洁,优雅。
接下来我们来实现创建群聊的功能,首先我们先创建一个创建群聊的数据包,里面包含一个List用来存储多个用户标识。
接下来我们在服务端创建处理创建群聊请求的Handler,CreateGroupRequestHandler继承SimpleChannelInboundHandler限定泛型为<CreateGroupRequestPacket>,覆写channelRead0方法。
服务端处理主要分为四步,第一步根据发来的用户信息从已登录用户中筛选用户的连接,这里Netty为我们提供了连接分组功能,十分贴心,我们将A,B,C三个用户的连接筛选出来后放入channelGroup,第二部创建群聊创建响应数据包CreateGroupResponsePacket。
第三步向channelGroup写入数据包,第四部保存群组映射关系,为后面群组管理与消息群发做准备。
最后在客户端添加对于群组创建响应的逻辑处理器MessageResponseHandler,用于将响应消息打印到控制台。
下一节,我们将会继续实现群组管理功能。