im源码分析(teamtalk)--RouteServer

im源码分析(teamtalk)系列:

1. im源码分析(teamtalk)–LoginServer
2. im源码分析(teamtalk)–RouteServer
3. im源码分析(teamtalk)–DbProxyServer

RouteServer介绍

RouteServer: 路由服务器,在存在多个MsgServer的情况下,用户可能登陆在不同的MsgServer上,这个时候就需要RouteServer进行转发。

源码分析

void CRouteConn::HandlePdu(CImPdu* pPdu)
{
	switch (pPdu->GetCommandId()) {
        case CID_OTHER_HEARTBEAT:
            // do not take any action, heart beat only update m_last_recv_tick
            break;
        case CID_OTHER_ONLINE_USER_INFO:
            _HandleOnlineUserInfo( pPdu );
            break;
        case CID_OTHER_USER_STATUS_UPDATE:
            _HandleUserStatusUpdate( pPdu );
            break;
        case CID_OTHER_ROLE_SET:
            _HandleRoleSet( pPdu );
            break;
        case CID_BUDDY_LIST_USERS_STATUS_REQUEST:
            _HandleUsersStatusRequest( pPdu );
            break;
        case CID_MSG_DATA:
        case CID_SWITCH_P2P_CMD:
        case CID_MSG_READ_NOTIFY:
        case CID_OTHER_SERVER_KICK_USER:
        case CID_GROUP_CHANGE_MEMBER_NOTIFY:
        case CID_FILE_NOTIFY:
        case CID_BUDDY_LIST_REMOVE_SESSION_NOTIFY:
            _BroadcastMsg(pPdu, this);
            break;
        case CID_BUDDY_LIST_SIGN_INFO_CHANGED_NOTIFY:
            _BroadcastMsg(pPdu);
            break;
        
	default:
		log("CRouteConn::HandlePdu, wrong cmd id: %d ", pPdu->GetCommandId());
		break;
	}
}

_HandleOnlineUserInfo
更新在线用户的信息,只有变更的用户信息,不是所有的。
_HandleUserStatusUpdate
用户多点多端登录的处理逻辑。
_HandleRoleSet
设置MsgServer的主路由服务
_HandleUsersStatusRequest

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);
}

刷新好友状态;
_BroadcastMsg
向MsgServer广播信息。

问题:RouteServer已经有所有用户id的在线状态和连接信息,为什么所有的消息都要广播?

个人推测这可能是要改进的一个点,在多个MsgServer存在的情况下完全可以根据用户id定向转发消息,这样能减少网络资源的浪费。

延伸:存在多个RouteServer的情况下,如何保证消息的唯一性?

OK,这就用到_HandleRoleSet这个接口了:
MsgServer在启动后会主动去RouteServer去注册,并把当前所有在线的用户信息告知RouterServer,然后在所有RouteServer列表中选择一个主路由服务(触发RouterServer的_HandleRoleSet接口),所有的转发消息只走主路由服务
冗余的RouteServer做为备份,在主RouteServer挂掉的情况下,提高可用性。

teamtalk安卓源码是一款开源的即时通讯应用程序的源代码。它基于C++和Java开发,具有跨平台的特性,可以在安卓设备上使用。通过对teamtalk安卓源码的剖析,我们可以深入了解其工作原理和实现细节。 首先,在剖析过程中,我们会看到teamtalk安卓源码的整体架构。它主要由客户端和服务器端两部分组成。客户端负责用户界面和交互逻辑的展示,服务器端负责数据存储和通信管理。双方通过TCP/IP协议进行通信。 其次,我们会发现teamtalk安卓源码具有丰富的功能。用户可以注册账号、登录、添加好友、发送文字和语音消息、创建群组等。它支持即时消息的收发、离线消息的存储和推送,还提供了消息撤回和删除的功能。此外,它还支持实时语音和视频通话,可以进行多人会议。 在剖析过程中,我们还会了解其核心技术点。比如,teamtalk安卓源码使用了SQLite数据库进行数据存储,使用了音视频编解码技术来保证语音和视频通话的质量。另外,它采用了高效的网络通信协议和算法,保证了数据的安全性和实时性。 此外,我们也会注意到teamtalk安卓源码的可扩展性和开放性。它提供了丰富的接口和插件机制,允许开发者进行二次开发和定制。开发者可以根据自己的需求,添加新的功能和扩展。 总的来说,通过对teamtalk安卓源码的剖析,我们可以了解到它是一款功能强大、可扩展的即时通讯应用程序。它不仅具有各种基本的通信功能,还提供了高质量的语音和视频通话能力。对于开发者来说,通过深入研究其源码,可以获取到宝贵的经验和技术知识。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值