简介
TcpServer实现了多线程主从Reactor服务器
结构
Acceptor新连接回调:
void newConnection(int sockfd, const InetAddress& peerAddr);
TcpConnection的四个回调
void setConnectionCallback(const ConnectionCallback& cb)
{ connectionCallback_ = cb; }
/// Set message callback.
/// Not thread safe.
void setMessageCallback(const MessageCallback& cb)
{ messageCallback_ = cb; }
/// Set write complete callback.
/// Not thread safe.
void setWriteCompleteCallback(const WriteCompleteCallback& cb)
{ writeCompleteCallback_ = cb; }
void removeConnection(const TcpConnectionPtr& conn);
事件循环线程池线程启动初始回调:
void setThreadInitCallback(const ThreadInitCallback& cb)
{ threadInitCallback_ = cb; }
Acceptor连接回调
- 从事件循环池中轮循方式选取一个
- 创建TcpConnection,将TcpServer设置的
connectionCallback_
,messageCallback_
和writeCompleteCallback_
传递到TcpConnection,同时设置关闭连接的回调removeConnection
- 创建连接建立的任务
connectEstablished
放入连接事件循环的队列中异步执行
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));
}
连接建立回调connectEstablished
- 设置连接状态为kConnected
- 事件通道绑定连接对象,开启读事件
- 执行事件回调
connectionCallback_
void TcpConnection::connectEstablished()
{
loop_->assertInLoopThread();
assert(state_ == kConnecting);
setState(kConnected);
channel_->tie(shared_from_this());
channel_->enableReading();
connectionCallback_(shared_from_this());
}
关闭连接回调
- 添加任务
removeConnectionInLoop
到acceptor所在的事件循环队列中异步执行 - 连接容器中删除对应连接
- 添加任务
connectDestroyed
到连接所在的事件循环队列中异步执行
void TcpServer::removeConnection(const TcpConnectionPtr& conn)
{
// FIXME: unsafe
loop_->runInLoop(std::bind(&TcpServer::removeConnectionInLoop, this, conn));
}
void TcpServer::removeConnectionInLoop(const TcpConnectionPtr& conn)
{
loop_->assertInLoopThread();
LOG_INFO << "TcpServer::removeConnectionInLoop [" << name_
<< "] - connection " << conn->name();
size_t n = connections_.erase(conn->name());
(void)n;
assert(n == 1);
EventLoop* ioLoop = conn->getLoop();
ioLoop->queueInLoop(
std::bind(&TcpConnection::connectDestroyed, conn));
}