路由相关信令和协议设计
enum BuddyListCmdID {
// ...... 暂时省略无关信令
CID_BUDDY_LIST_USERS_STATUS_REQUEST = 522,
CID_BUDDY_LIST_USERS_STATUS_RESPONSE = 523,
// ...... 暂时省略无关信令
};
message IMUsersStatReq{
//cmd id: 0x020a
required uint32 user_id = 1;
repeated uint32 user_id_list = 2;
optional bytes attach_data = 20;
}
message IMUsersStatRsp{
//cmd id: 0x020b
required uint32 user_id = 1;
repeated IM.BaseDefine.UserStat user_stat_list = 2;
optional bytes attach_data = 20;
}
enum UserStatType{
USER_STATUS_ONLINE = 1;
USER_STATUS_OFFLINE = 2;
USER_STATUS_LEAVE = 3;
}
流程图
![请添加图片描述](https://i-blog.csdnimg.cn/direct/2c174eb8326946adae40b9891a0c74b4.jpeg)
具体代码逻辑
- 在 g_user_map 中根据 user_id 查找对应的状态
- 如果不在列表设置为下线状态;如果在列表设置为对应的状态;
- 组包回复
void CRouteConn::_HandleUsersStatusRequest(CImPdu* pPdu)
{
IM::Buddy::IMUsersStatReq msg;
CHECK_PB_PARSE_MSG(msg.ParseFromArray(pPdu->GetBodyData(), pPdu->GetBodyLength()));
uint32_t request_id = msg.user_id();
uint32_t query_count = msg.user_id_list_size();
log("HandleUserStatusReq, req_id=%u, query_count=%u ", request_id, query_count);
IM::Buddy::IMUsersStatRsp msg2;
msg2.set_user_id(request_id);
msg2.set_attach_data(msg.attach_data());
list<user_stat_t> result_list;
user_stat_t status;
for(uint32_t i = 0; i < query_count; i++)
{
IM::BaseDefine::UserStat* user_stat = msg2.add_user_stat_list();
uint32_t user_id = msg.user_id_list(i);
user_stat->set_user_id(user_id);
CUserInfo* pUser = GetUserInfo(user_id);
if (pUser) {
user_stat->set_status((::IM::BaseDefine::UserStatType) pUser->GetStatus()) ;
}
else
{
user_stat->set_status(USER_STATUS_OFFLINE) ;
}
}
// send back query user status
CImPdu pdu;
pdu.SetPBMsg(&msg2);
pdu.SetServiceId(SID_BUDDY_LIST);
pdu.SetCommandId(CID_BUDDY_LIST_USERS_STATUS_RESPONSE);
pdu.SetSeqNum(pPdu->GetSeqNum());
SendPdu(&pdu);
}
CUserInfo* GetUserInfo(uint32_t user_id)
{
CUserInfo* pUser = NULL;
UserInfoMap_t::iterator it = g_user_map.find(user_id);
if (it != g_user_map.end()) {
pUser = it->second;
}
return pUser;
}