im源码分析(teamtalk)--LoginServer

im源码分析(teamtalk)系列:

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

LoginServer功能介绍

登陆服务器,主要作用是实现负载均衡,分配一个负载小的MsgServer给客户端使用。这里的负载较小是指MsgServer的tcp连接数大小。

源码分析

1.交互服务

	int ret = netlib_init();

	if (ret == NETLIB_ERROR)
		return ret;
	CStrExplode client_listen_ip_list(client_listen_ip, ';');
	for (uint32_t i = 0; i < client_listen_ip_list.GetItemCnt(); i++) {
		ret = netlib_listen(client_listen_ip_list.GetItem(i), client_port, client_callback, NULL);
		if (ret == NETLIB_ERROR)
			return ret;
	}

	CStrExplode msg_server_listen_ip_list(msg_server_listen_ip, ';');
	for (uint32_t i = 0; i < msg_server_listen_ip_list.GetItemCnt(); i++) {
		ret = netlib_listen(msg_server_listen_ip_list.GetItem(i), msg_server_port, msg_serv_callback, NULL);
		if (ret == NETLIB_ERROR)
			return ret;
	}
    
    CStrExplode http_listen_ip_list(http_listen_ip, ';');
    for (uint32_t i = 0; i < http_listen_ip_list.GetItemCnt(); i++) {
        ret = netlib_listen(http_listen_ip_list.GetItem(i), http_port, http_callback, NULL);
        if (ret == NETLIB_ERROR)
            return ret;
    }

这里一共监听三个端口,并注册了回调函数:
client_callback:监听客户端tcp请求
msg_serv_callback:监听MsgServer连接
http_callback:监听http请求

2.主要功能

主要有三个功能:

private:
	// MsgServer连接请求,会把msgserver连接数和ip等信息告知Loginserver
	void _HandleMsgServInfo(CImPdu* pPdu);
	// 用户数更新,MsgServer新增连接或减少连接,更新LoginServer记录的个数
	void _HandleUserCntUpdate(CImPdu* pPdu);
	// 请求MsgServer地址,分两个接口,一个是http请求,一个是客户端的长连接请求
	void _HandleMsgServRequest(CImPdu* pPdu);

看一下LoginServer这边保存的都有哪些MsgServer的信息

typedef struct  {
    string		ip_addr1;	// 电信IP
    string		ip_addr2;	// 网通IP
    uint16_t	port;
    uint32_t	max_conn_cnt;	// 最大连接数
    uint32_t	cur_conn_cnt;   // 当前连接数,实时更新
    string 		hostname;	// 消息服务器的主机名
} msg_serv_info_t;

如何进行负载均衡

找到连接数最少的MsgServer,并且不超过该MsgServer的最大连接数:

	// return a message server with minimum concurrent connection count
	msg_serv_info_t* pMsgServInfo;
	uint32_t min_user_cnt = (uint32_t)-1;
	map<uint32_t, msg_serv_info_t*>::iterator it_min_conn = g_msg_serv_info.end(),it;

	for (it = g_msg_serv_info.begin() ; it != g_msg_serv_info.end(); it++) {
		pMsgServInfo = it->second;
		if ( (pMsgServInfo->cur_conn_cnt < pMsgServInfo->max_conn_cnt) &&
			 (pMsgServInfo->cur_conn_cnt < min_user_cnt))
        {
			it_min_conn = it;
			min_user_cnt = pMsgServInfo->cur_conn_cnt;
		}
	}
发布了59 篇原创文章 · 获赞 22 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/Martin_chen2/article/details/90903334
IM