1. 简介
CGroupMessageModel用于mysql redis管理记录群消息信息
2. 类与接口
① bool sendMessage(uint32_t nFromId, uint32_t nGroupId, IM::BaseDefine::MsgType nMsgType, uint32_t nCreateTime,uint32_t nMsgId, const string& strMsgContent)
发消息,向mysql IMGroupMessage_x插入该群消息信息
插入成功返回true,失败返回false
② bool sendAudioMessage(uint32_t nFromId, uint32_t nGroupId, IM::BaseDefine::MsgType nMsgType, uint32_t nCreateTime, uint32_t nMsgId, const char* pMsgContent, uint32_t nMsgLen)
发送语音消息,先上传语音文件,同时记录向mysql IMAudio表新增语音信息记录,若上传成功才会继续向mysql IMGroupMessage_x插入该群消息信息
上述所有流程成功才会返回true,否则返回false
③ bool clearMessageCount(uint32_t nUserId, uint32_t nGroupId)
重置redis unread库key为groupid_im_group_msg和userid_groupid_im_user_group的hash表计数信息,其中group_im_group_msg用于记录群组groupid所有消息数,userid_groupid_im_user_group记录用户userid已读群组groupid消息数
重置成功返回true,失败返回false
④ bool incMessageCount(uint32_t nUserId, uint32_t nGroupId)
增加群消息计数,redis unread库key为groupid_im_group_msg和userid_groupid_im_user_group的hash表计数信息同步加1
成功返回true,失败返回false
⑤ void getMessage(uint32_t nUserId, uint32_t nGroupId, uint32_t nMsgId, uint32_t nMsgCnt, list<IM::BaseDefine::MsgInfo>& lsMsg)
获取群组消息列表,从mysql IMGroupMessage_x表拉取用户nUserId加入nGroupId最新的nMsgCnt消息记录,结果存放到lsMsg
⑥ void getUnreadMsgCount(uint32_t nUserId, uint32_t &nTotalCnt, list<IM::BaseDefine::UnreadInfo>& lsUnreadCount)
获取用户群未读消息计数,从redis unread库相关哈希表记录中计算出未读消息数(groupid_im_group_msg计数 - groupid_im_group_msg计数),未读数存到nTotalCnt,消息详情存到lsUnreadCount
⑦ uint32_t getMsgId(uint32_t nGroupId)
获取一个群组的msgId,redis unread库key为group_msg_id_groupid的字符串value同时自增1(INCRYBY)
返回自增后的msgid
⑧ void getLastMsg(uint32_t nGroupId, uint32_t &nMsgId, string &strMsgData, IM::BaseDefine::MsgType &nMsgType, uint32_t& nFromId)
获取一个群的最后一条消息,通过查询mysql IMGroupMessage_x表获得,结果通过第2-4个参数返回
⑨ void getUnReadCntAll(uint32_t nUserId, uint32_t &nTotalCnt)
获取某个用户所有群的所有未读计数之和,计算方法参考getUnreadMsgCount,结果通过nTotalCnt返回
⑩ void getMsgByMsgId(uint32_t nUserId, uint32_t nGroupId, const list<uint32_t> &lsMsgId, list<IM::BaseDefine::MsgInfo> &lsMsg)
查询mysql IMGroupMessage_x表,获取msgid在lsMsgId里的消息,消息详情保存到lsMsg
⑪ bool resetMsgId(uint32_t nGroupId)
重置一个群组的msgId,将redis unread库key为group_msg_id_groupid的字符串value置0
成功返回true,失败返回false
3. mysql IMGroupMessage_1信息
mysql> select * from IMGroupMessage_1;
+----+---------+--------+-------+----------------------------------------------+------+--------+------------+------------+
| id | groupId | userId | msgId | content | type | status | updated | created |
+----+---------+--------+-------+----------------------------------------------+------+--------+------------+------------+
| 1 | 1 | 1 | 1 | xOb240V1N2lHz69lHLO25Q== | 17 | 0 | 1646811088 | 1646811088 |
| 2 | 1 | 18 | 2 | 5kqJlYtkl/nS/tK0nH5C5wr+GZ43+2mMfQMFqTsGBjY= | 17 | 0 | 1646811691 | 1646811691 |
| 3 | 1 | 1 | 3 | xOb240V1N2lHz69lHLO25Q== | 17 | 0 | 1648468589 | 1648468589 |
+----+---------+--------+-------+----------------------------------------------+------+--------+------------+------------+
3 rows in set (0.03 sec)
4. redis unread库群组信息
127.0.0.1:6379[1]> keys *
1) "17_1_im_user_group"
2) "msg_id_2"
3) "1_im_group_msg"
4) "last_update_group"
5) "total_user_update"
6) "1_1_im_user_group"
7) "18_1_im_user_group"
8) "group_msg_id_1"
127.0.0.1:6379[1]> get group_msg_id_1
"3"
127.0.0.1:6379[1]> hgetall 1_im_group_msg
1) "count"
2) "3"
127.0.0.1:6379[1]> hgetall 18_1_im_user_group
1) "count"
2) "2"
127.0.0.1:6379[1]>
5. test_groupmsgmodel.cpp
//
// test_groupmsgmodel.cpp
// test_groupmsgmodel
//
// Created by blueBling on 22-04-07.
// Copyright (c) 2022年blueBling. All rights reserved.
//
#include "GroupMessageModel.h"
#include<iostream>
using std::cout;
using std::endl;
// 测试用户id为18所有未读消息数(该用户仅在群组id为1的群组里)
// redis unread库 key为1_im_group_msg的hash表保存了群组id为1所有消息数
// redis unread库 key为18_1_im_user_group的hash表保存了用户id为18的用户在群组id为1的所有已读消息数
int test_getunreadmsgcnt() {
uint32_t nTotalCnt = 0;
list<IM::BaseDefine::UnreadInfo> lsUnreadCount;
CGroupMessageModel::getInstance()->getUnreadMsgCount(18, nTotalCnt, lsUnreadCount);
cout << "nTotalCnt:" << nTotalCnt << endl;
// message UnreadInfo{
// required uint32 session_id = 1;
// required SessionType session_type = 2;
// required uint32 unread_cnt = 3;
// required uint32 latest_msg_id = 4;
// required bytes latest_msg_data = 5;
// required MsgType latest_msg_type = 6;
// required uint32 latest_msg_from_user_id = 7; //发送得用户id
// }
for(const auto &item : lsUnreadCount) {
cout << "session_id:" << item.latest_msg_id();
cout << " session_type:" << item.session_type();
cout << " unread_cnt:" << item.unread_cnt();
cout << " latest_msg_id:" << item.latest_msg_id();
cout << " latest_msg_data:" << item.latest_msg_data();
cout << " latest_msg_type:" << item.latest_msg_type();
cout << " latest_msg_from_user_id:" << item.latest_msg_from_user_id();
cout << endl;
}
return 0;
}
int main(){
test_getunreadmsgcnt();
//这里mysql和redis连接池未释放存在内存泄漏问题,解决方法参考test_dbpool
return 0;
}
运行结果
nTotalCnt:1
session_id:3 session_type:2 unread_cnt:1 latest_msg_id:3 latest_msg_data:xOb240V1N2lHz69lHLO25Q== latest_msg_type:17 latest_msg_from_user_id:1
6. 源码
测试demo: tests/test_groupmsgmodel.cpp