标签:
本节研究服务器TcpServer的实现;
(1)TcpServer由用户直接使用,生命周期由用户控制,用户设置好相应的回调MessageCallback、ConnectionCallback传递给TcpServer即可;MessageCallback为连接上有接收数据时调用的回调(处理业务逻辑),这些数据存放在连接的应用层接收缓冲区中;ConnectionCallback在连接建立和断开时,都会直接的回调,主要是通知用户进行相应的处理;
(2)在TcpServer中,建立连接描述符和TcpConnection之间的关系,通过stl中map来实现,map<int, TcpConnectionPtr>这样可以高效的查找,删除,插入操作;
(3)TcpServer本身有一个EventLoop,主要用于对接受连接事件的监听,;EventLoopPool也为TcpServer的成员,使用轮转法为每一个新的TcpConnection选择EventLoop;
示意图如下:
class TcpConnection;
class EventLoop;
class Acceptor;
class EventLoopPool;
class TcpServer final
{
public:
TcpServer(const TcpServer&) = delete;
TcpServer& operator=(const TcpServer&) = delete;
explicit TcpServer(EventLoop* loop, const InetAddress& serverAddr, size_t loopNums);
void start();
typedef std::shared_ptr<TcpConnection> TcpConnectionPtr;
void setMessageCallback(const MessageCallback& cb)
{
_messageCallback = cb;
}
void setConnectionCallback(const ConnectionCallback& cb)
{
_connectionCallback = cb;
}
private:
void _newConnection(int connfd, const InetAddress& peerAddr);
void _removeConnection(const TcpConnectionPtr& conn);
void _removeConnectionInLoop(const TcpConnectionPtr& conn);
InetAddress _serverAddr;
size_t _loopNums;
EventLoop* _loop;
std::unique_ptr<Acceptor> _acceptor;
std::unique_ptr<EventLoopPool> _loopPool;
std::map<int, TcpConnectionPtr> _connectionMaps;
MessageCallback _messageCallback;
ConnectionCallback _connectionCallback;
};说明几点:
(1)MessageCallback为连接上有接收数据时调用的回调(处理业务逻辑),这些数据存放在连接的应用层接收缓冲区中;ConnectionCallback在连接建立和断开时,都会直接的回调,主要是通知用户进行相应的处理;
(2)在TcpServer中,建立连接描述符和TcpConnection之间的关系,通过stl中map来实现,map<int, TcpConnectionPtr>这样可以高效的查找,删除,插入操作;
(3)TcpServer本身有一个EventLoop,由用户来传入,主要用于对接受连接的事件的监听;EventLoopPool也为TcpServer的成员,使用轮转法为每一个新的TcpConnection选择EventLoop;_loopNums为EventLoopPool的EventLoop数量;
(4)std::unique_ptr<Acceptor> _acceptor是TcpServer的成员,用于接受新连接,_newConnection为注册给_acceptor的回调,当有新连接时,会回调该函数;
(5)_serverAddr为服务器的监听地址;
TcpServer::TcpServer(EventLoop* loop, const InetAddress& serverAddr, size_t loopNums) :
_serverAddr(serverAddr),
_loopNums(loopNums),
_loop(loop),
_acceptor(new Acceptor(_serverAddr, _loop)),
_loopPool(_loopNums > 0 ? (new EventLoopPool(_loopNums)) : nullptr)
{
_acceptor->setNewConnectionCallback(std::bind(&TcpServer::_newConnection, this, std::placeholders::_1, std::placeholders::_2));
}
说明几点:
(1)当_loopNums不大于0时,就使用master线程中EventLoop进行对TcpConnection的管理,意味着这是一个单线程单EventLoop的服务器;
void TcpServer::start()
{
_loopPool->start();
}
void TcpServer::_newConnection(int connfd, const InetAddress& peerAddr)
{
EventLoop* loop;
if ( _loopPool)
{
loop = _loopPool->getNextLoop();
}
else
{
loop = _loop;
}
LOG_INFO << "TcpServer::_newConnection [" << connfd << "] from " << peerAddr.hostNameString();
TcpConnectionPtr conn(new TcpConnection(connfd, loop, peerAddr, _serverAddr));
assert(_connectionMaps.find(connfd) == _connectionMaps.end());
_connectionMaps[connfd] = conn;
conn->setMessageCallback(_messageCallback);
conn->setConnectionCallback(_connectionCallback);
conn->setCloseConnectionCallback(std::bind(&TcpServer::_removeConnection, this, std::placeholders::_1));
conn->connectEstablished();
}
说明几点:
(1)该函数只要由Acceptor中accept后新连接的回调函数;
(2)创建TcpConnection后,放入_connectionMaps中,这样TcpServer也就持有了TcpConnection,如果TcpServer不删除TcpConnection,那么TcpConnection是不会析构的;
(3)setMessageCallback,setConnectionCallback,setCloseConnectionCallback分别为设置信息接收时的用户回调,连接建立和断开时的用户回调,TcpServer连接断开回调;connectEstablished为让IO线程开始接管TcpConnection上的事件监听;
void TcpServer::_removeConnection(const TcpConnectionPtr& conn) //thread safe
{
_loop->queueInLoop(std::bind(&TcpServer::_removeConnectionInLoop, this, conn));
}
void TcpServer::_removeConnectionInLoop(const TcpConnectionPtr& conn)
{
LOG_DEBUG << "use_count: " << conn.use_count();
_connectionMaps.erase(conn->connfd());
LOG_DEBUG << "TcpServer::_removeConnection fd[" << conn->connfd() << "] " << conn.use_count();
}
说明几点:
(1)_removeConnection为上述TcpConnection通过setCloseConnectionCallback设置的TcpServer连接断开回调,最后连接断开时,为保证线程安全性,将会在TcpServer本身的EventLoop中进行真正的删除;
标签:
原文地址:http://blog.csdn.net/skyuppour/article/details/44873449