MsgServer 是 TeamTalk 中最关键的一个 server,它和 LoginServer,filerServer,RouteServer,DB_Prox_Server 都有联系。本文只谈 MsgServer 与 LoginServer 的交互的部分。
LoginServer中的” MsgServerListenIP” 和” MsgServerPort” 就是监听 MsgServer 连接的 IP 和 Port:
loginserver.conf
1
2
MsgServerListenIP=192.168.2.6 # can use multiple ip, seperate by ';'
MsgServerPort=8100
在 MsgServer 的参数配置文件 msgserver.conf 中,
1
2
3
4
5
ListenIP=192.168.2.6
ListenPort=8000
LoginServerIP1=192.168.2.6
LoginServerPort1=8100
其中 LoginServerIP1 和 LoginServerPort1 就是 loginserver.conf 中的 MsgServerListenIP 和 MsgServerPort;
ListenIP 和 ListenPort 是 MsgServer 监听客户连接的监听地址和端口。
核心类
在 MsgServer 和 LoginServer 通信的流程里,除了在LoginServer提到的基础 BaseSocket 和 EventDispatch 类,需要关注的新类是 base/imconn.h 和 LoginServConn.h;其中 CLoginServConn 继承自 CImConn;CImConn 和 CLoginServConn 主要功能是提供了 socket 回调函数,以及在 EPOLL 各个状态的 onRead,onWrite 之类的操作。
imconn.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class CImConn : public CRefObject
{
...
virtual void OnConnect(net_handle_t handle) { m_handle = handle; }
virtual void OnConfirm() {}
virtual void OnRead();
virtual void OnWrite();
virtual void OnClose() {}
virtual void OnTimer(uint64_t curr_tick) {}
virtual void OnWriteCompelete() {};
...
}
// 连接LoginServer的fd的回调函数
void imconn_callback(void* callback_data, uint8_t msg, uint32_t handle, void* pParam);
其中虚函数在 CLoginServConn 中得到了实现。
MsgServer 连接 LoginServer 流程
1> 利用 msgserver.conf 中的 ListenIP 和 ListenPort 建立监听;
2> msg_server.cpp 中调用init_login_serv_conn() 来连接 LoginServer,对于每一个 LoginServer(LoginServer 可以有很多个,我们这里只设置 1 个),调用 CLoginServConn:Connect() 进行连接,最后将 socket 和对应的 CLoginServConn 构建 pair 存储在 CLoginServConn.cpp 中的静态变量 g_login_server_conn_map 中。
3> 在 EventDispatch 中,只要 LoginServer accept MsgServer 后,对应的 socket 就会触发 EPOLLOUT,详情见:一种触发 EPOLLOUT 的情形。最终会回调 CLoginServConn::OnConfirm(),向 LoginServer 发送一个 CommandId 为” CID_OTHER_MSG_SERV_INFO” 的确认包。
4> 在 LoginServer 这一边,监听 MsgServer 连接的 listenfd 会调用 CLoginConn::HandlePdu(CImPdupPdu) 来处理,最终将 MsgServer 的信息保存在 LoginServer 的 map g_msg_serv_info 中。当客户连接 LoginServer 后,就从 g_msg_serv_info 中选一个负载较低的 MsgServer 返回给客户端。