TCPServer封装了Acceptor,并且自己提供了一个newConnection
函数,作为Acceptor的连接建立回调函数:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30void TcpServer::newConnection(int sockfd, const InetAddress& peerAddr)
{
loop_->assertInLoopThread();
EventLoop* ioLoop = threadPool_->getNextLoop();
char buf[64];
snprintf(buf, sizeof buf, "-%s#%d", ipPort_.c_str(), nextConnId_);
++nextConnId_;
string connName = name_ + buf;
LOG_INFO << "TcpServer::newConnection [" << name_
<< "] - new connection [" << connName
<< "] from " << peerAddr.toIpPort();
InetAddress localAddr(sockets::getLocalAddr(sockfd));
// FIXME poll with zero timeout to double confirm the new connection
// FIXME use make_shared if necessary
//建立一个TCPConnection,并设置相应的回调函数
TcpConnectionPtr conn(new TcpConnection(ioLoop,
connName,
sockfd,
localAddr,
peerAddr));
connections_[connName] = conn;
conn->setConnectionCallback(connectionCallback_);
conn->setMessageCallback(messageCallback_);
conn->setWriteCompleteCallback(writeCompleteCallback_);
conn->setCloseCallback(
boost::bind(&TcpServer::removeConnection, this, _1)); // FIXME: unsafe
ioLoop->runInLoop(boost::bind(&TcpConnection::connectEstablished, conn));
}
跟TCPConnection一样,TCPServer对外提供了事件处理回调函数接口,并将这些回调函数注册到TCPConnection中。TCPServer还提供了一个ConnectionCallBack
函数,该函数也是直接注册到TCPConnection中,用来在链接建立后执行,比如可以在设置高水位处理函数以及写完成处理函数:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20...
server_.setConnectionCallback(
boost::bind(&SudokuServer::onConnection, this, _1));
...
...
void onConnection(const TcpConnectionPtr& conn)
{
LOG_TRACE << conn->peerAddress().toIpPort() << " -> "
<< conn->localAddress().toIpPort() << " is "
<< (conn->connected() ? "UP" : "DOWN");
if (conn->connected())
{
if (tcpNoDelay_)
conn->setTcpNoDelay(true);
conn->setHighWaterMarkCallback(
boost::bind(&SudokuServer::highWaterMark, this, _1, _2), 5 * 1024 * 1024);
bool throttle = false;
conn->setContext(throttle);
}
}
TCPServer通过一个map来保存所有已经建立的链接:1
2typedef std::map<string, TcpConnectionPtr> ConnectionMap;
ConnectionMap connections_;
channel->TCPConnection->TCPServer每一个类有着自己的任务以及需要维护的属性,层与层之间通过回调函数来进行控制,上一层通过注册回调函数来控制下一层的事件操作以及维护自己的属性,下一层负责处理自己维护的属性以及执行上一层所注册的函数,从而实现每一层的信息维护以及上一层对下一层的操作控制。
利用注册回调函数,我们可以在不需要继承任何基类的情况下,通过TCPServer实现自己的服务器。对于不同功能的服务器,只需要提供自己的相关事件处理函数并注册到TCPServer中,就可以了!