文章目录
1.修改代码调试 回到对应的源码目录:比如im/server/src/db_proxy_server
2.服务器服务划分
必须的server部分
1.login_server
2.msg-server
3.route_server
4.db_proxy_server
非必须的server部分
1.push_server 手机端对应类似微信的提示信息的时候才需要
2.file_server 我们床送文件的时候才需要
3.http_msg_server 我们对外提供http api接口的时候才需要
4.msfs 存储文件(HTTP上传下载图片,例如发送图片才需要,文件聊天不需要)
3.数据库代理服务器设计
main函数主流程
1.CacheManager 开启redis类似连接池的设置
2.CDBManager 开启mysql连接池的设置
3.CAudioModel 开启音频存储(语音加密)
4.很多巴拉巴拉Model操作数据库的操作
5.CRelationModel单聊,两者的关系库
6.初始化线程池
7.启动群会话同步CSyncCenter::getInstance()->startSync()
8.监听端口,创建reactor模型
- 准备过程
1.CHandlerMap::init()对所有指令id和回调函数进行绑定
- 总体流程:
〇msg_server<->db_proxy_server连接,之间创建CProxyConn
①有Pdu的数据包发送给CProxyServer数据库代理服务器,
②数据库代理服务求用HandlerPduBuf函数解析传过来的Pdu数据包,根据包的commandId来使用GetHandler找到对应的处理函数,
(补充:处理函数都放在map或一个unordered_map里面,根据commandId去找)
③根据包头指定的uuid找到对应处理函数后,再创建任务
④当找到的处理函数不为空,把创建好的任务放到一个list里面,也就是上面的
g_thread_pool.AddTask(pTask),AddTask这个函数会通过%worker_size的方式均匀得给线程分配任务,每个线程都有自己的任务队列
⑤每个线程循环调用Execute(),
登录
业务处理结束后,将登录成功的数据进行回发
reactor相应流程
上面有讲过
1.初始化线程池和连接池
2.在数据怎么存?
mysql表设计(存在IMGroupMessage表里面):
(启动的时候更新到redis,运行中都是要操作到mysql和redis)
redis存储在hash表中:
函数说明:
redis缓存
消息计数(单聊和群聊)
未读消息机制
- 1.单聊
key值:"unread_” + int2string(nUserId)
原理:使用一个hashset存储一个user_id对应不同聊天的未读消息数量
图示:
from id为用户的id,unread_cut为未读消息数量
函数名字:
删除消息:只要删除unread_id对应的单独key-value就行
- 2.群聊未读消息
删除群聊未读消息:更新user_id + group_id + _im_user_group对应的value和group_id + _im_group_msg一直,也就是:群消息数 = 已读消息数,
原理:
1)group_id + _im_group_msg 每发一个群消息,群消息计数+1
2)user_id + group_id + _im_user_group 每个人都维护自己的已读计数
群成员管理
单聊群聊
- 1.单聊
key值设定:“msg_id_” + nRelateId
函数:uint32_t CMessageModel::getMsgId(uint32_t nRelateId)
说明:
1)两个聊天,消息ID是共用的
2)两个人的ID映射出唯一的ID,这个ID是通过自增出来的,先去查存不存再,不存在就新建
3)怎么映射ID的key,如下表
表的设计:
具体函数:
单聊流程图:
- 2.群聊:
key值设定:“group_msg_id_” + group_id
函数: uint32_t CGroupMessageModel::getMsgId(uint32_t nGroupId)群聊流程图