路由相关信令和协议设计
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;
}
流程图

具体代码逻辑
-
在 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;
}