6 ChatRoom实现
ChatRoom是聊天室最核心的业务单元,核心逻辑聊天就是在聊天室内完成。
聊天室的主要职责是维护房间自身状态,管理聊天用户,以及转发聊天消息。
维护房间状态
房间本身有一些属性信息,包括房间ID、创建者ID,这些信息用来进行身份识别和查询。
还有房间创建时间、房间有效生存时间(过期后需要销毁),房间人数上限,房间当前状态等。这些信息主要用于控制聊天室生命周期。
enum ROOM_STATUS
{
RS_NORMAL = 1,
RS_DESTROY,
};
public:
int m_id;
int64_t m_nCreaterID;
private:
time_t m_timeCreate;
int m_nLiftTime;
int m_nMaxPlayerCount;
ROOM_STATUS m_eStatus;房间ID得范围室100000-999999,所以使用int表示即可。用户id使用64位。
房间状态暂时只设置了两个,一个是正常状态,一个是即将销毁得状态。当房间处于销毁状态时,不再接收新的用户加入房间。
房间的初始状态在初始化时设置
管理聊天用户
聊天室要维护一个用户列表,用户进入聊天室,离开聊天室,用户列表都会发生变化。
我们使用unordered_map维护用户列表,key为用户id,value为用户user指针。并且使用互斥锁保护列表在多线程下得访问安全。
管理用户的几个业务场景如下

加入房间
加入房间的判断,先确定房间是否达到人数上限,再判断是否是销毁状态,如果都没问题的话,将用户加入到用户map中。
在RoomMgr里,加入房间的请求会先检测是否已经在某个房间,因此这里并没有进行重复加入的判断。
离开房间
离开房间直接移除关系即可,注意对map进行了保护。
查询是否在房间
检测map中是否存在用户id即可。
房间消息发送
服务收到用户发送聊天室消息的请求,会通过RoomMgr转到对应的聊天室,聊天室负责将消息发送到聊天室内每个人那里。
首先,判断发送消息的人,是否室聊天室内的用户,不是的话不处理。
组装消息,采用json格式,将发送者昵称赋值给sender,消息内容赋值给msg,HYHEADER类型的消息拼装之前介绍过,这里不再重复。
最后,遍历聊天室的用户列表,调用每个user的SendMsg方法,将消息广播到聊天室内每个人的客户端。
这是最普通的消息发送,我们通过修改消息参数,可以做到给聊天室内的某个人或某些人发送消息,而对其他人屏蔽,当然这得看具体的业务需求。
房间删除逻辑
房间内部,在定时Check的时候,检测是否达到删除的标准。
当房间有人时,房间会一直保持,只有房间过期后,房间里没人了(无论是从来没有人进入,还是进入的人都离开了),会触发删除逻辑。
聊天室检测到符合删除的逻辑时,需要通知房间管理类,此处使用了发送事件的方式PostEvent。
当RoomMgr收到聊天室的删除通知时,会再调用聊天室的DestroyRoom方法,执行房间清理逻辑。
在上一节中,我们实现RoomMgr时,在构造函数中监听了销毁房间的事件,并注册了对应的处理函数。两处逻辑结合在一起,形成了完整的闭环。
到这里ChatRoom的实现就完成了。
当然,细心的朋友会发现,还少一个获取房间内用户列表的一个消息请求和处理,不过,数据都有,消息通道也完成了,实现还有什么难度吗?这就交给聪明的你加上吧。
最后,附上完整的ChatRoom头文件
Last updated