服务端类,一个服务端只需要一个实例。该类的功能是管理accept获取的TcpConnection。
TcpServer::TcpServer(EventLoop* loop,
const InetAddress& listenAddr,
const string& nameArg,
Option option)
: loop_(CHECK_NOTNULL(loop)),
ipPort_(listenAddr.toIpPort()),
name_(nameArg),
acceptor_(new Acceptor(loop, listenAddr, option == kReusePort)),
threadPool_(new EventLoopThreadPool(loop, name_)),
connectionCallback_(defaultConnectionCallback),
messageCallback_(defaultMessageCallback),
nextConnId_(1)
{
acceptor_->setNewConnectionCallback(
std::bind(&TcpServer::newConnection, this, _1, _2));
}
TcpServer::~TcpServer()
{
loop_->assertInLoopThread();
LOG_TRACE << "TcpServer::~TcpServer [" << name_ << "] destructing";
for (auto& item : connections_)
{
TcpConnectionPtr conn(item.second);
item.second.reset();
conn->getLoop()->runInLoop(
std::bind(&TcpConnection::connectDestroyed, conn));
}
}
构造函数中涉及的Acceptor、EventLoopThreadPool等在之前都分析过了,可以参看之前的博客。
向Acceptor类注册建立连接后的回调函数。
void 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
TcpConnectionPtr conn(new TcpConnection(ioLoop,
connName,
sockfd,
localAddr,
peerAddr));
connections_[connName] = conn;
conn->setConnectionCallback(connectionCallback_);
conn->setMessageCallback(messageCallback_);
conn->setWriteCompleteCallback(writeCompleteCallback_);
conn->setCloseCallback(
std::bind(&TcpServer::removeConnection, this, _1)); // FIXME: unsafe
ioLoop->runInLoop(std::bind(&TcpConnection::connectEstablished, conn));
}
在该回调函数中,主要的功能就是创建一个表示连接的类对象。这也就是TcpConnection类的作用,表示一个连接。并注册连接、收到消息、写完成、关闭的回调函数,当相应的事件发生时由TcpConnection调用。由于连接已经建立,所以直接调用了TcpConnection的TcpConnection::connectEstablished(),并在TcpConnection::connectEstablished()中调用了表示连接的回调函数。表示连接和收到消息的回调函数可以是由用户注册的,也可能是在构造函数中设置的默认的。表示关闭的回调函数是TcpServer的TcpServer::removeConnection(),在分析TcpConnection类的时候讲过这个接口,这里不再细说了。
void TcpServer::setThreadNum(int numThreads)
{
assert(0 <= numThreads);
threadPool_->setThreadNum(numThreads);
}
void TcpServer::start()
{
if (started_.getAndSet(1) == 0)
{
threadPool_->start(threadInitCallback_);
assert(!acceptor_->listening());
loop_->runInLoop(
std::bind(&Acceptor::listen, get_pointer(acceptor_)));
}
}
设置线程数,之前在将EventLoopThreadPool时说过,就是创建多个event loop。实现多线程服务端。
TcpServer::start()允许多次调用,但只有一次有效,这里采用的原子操作。服务端的启动也就是开启监听功能。
虽然该类是表示服务端的类,但实际上该类本身的接口非常少,都是间接使用其他类实现的各个功能。所以这里也不再多说了。参看之前的博客即可。