作用

TcpServer 类是基于事件驱动模型的 TCP 服务器核心实现,整合了连接管理、线程池调度、定时任务等功能,支持高并发连接处理。以下是各部分代码的详细解释,包括核心成员、函数逻辑及与其他组件的协作关系:

TcpServer 核心成员解析

成员变量类型 / 说明核心作用
_next_iduint64_t自动增长的连接 ID 生成器,用于唯一标识每个客户端连接
_portint服务器监听的端口号
_timeoutint非活跃连接超时时间(单位:通常为秒),超过此时长未通信的连接会被自动销毁
_enable_inactive_releasebool是否启用非活跃连接自动销毁功能(true 表示启用)
_acceptorAcceptor监听套接字管理器,负责绑定端口、监听连接请求,并在新连接到来时触发回调
_baseloopEventLoop主线程的事件循环,负责处理监听套接字的 accept 事件和服务器核心逻辑
_poolLoopThreadPool从属事件循环线程池,用于负载均衡处理客户端连接的 IO 事件(避免主线程阻塞)
_connsstd::unordered_map<uint64_t, PtrConnection>存储所有客户端连接的哈希表(键为连接 ID,值为连接对象的智能指针 PtrConnection
ConnectedCallbackstd::function 类型外部注册的回调函数,在"连接建立"事件发生时触发
MessageCallbackstd::function 类型外部注册的回调函数,在"收到消息"事件发生时触发
ClosedCallbackstd::function 类型外部注册的回调函数,在"连接关闭"事件发生时触发
AnyEventCallbackstd::function 类型外部注册的回调函数,在"任意事件"发生时触发

服务器初始化与启动

构造函数 TcpServer(int port)

TcpServer(int port) : _port(port),
_next_id(0),
_enable_inactive_release(false),
_acceptor(&_baseloop, port),
_pool(&_baseloop)
{
_acceptor.SetAcceptCallback(std::bind(&TcpServer::NewConnection, this, std::placeholders::_1));
_acceptor.Listen(); // 将监听套接字挂到baseloop上
}

初始化逻辑:
初始化端口、连接 ID 生成器,默认禁用非活跃连接销毁。

创建 _acceptor(绑定主线程 _baseloop 和端口),并注册新连接回调 NewConnection(当有客户端连接时调用)。

调用 _acceptor.Listen() 启动监听(将监听套接字的可读事件注册到 _baseloop 的 Poller 中)。

Start():启动服务器

void Start()
{
_pool.Create();    // 创建线程池中的从属线程
_baseloop.Start(); // 启动主线程事件循环
}

作用:启动服务器核心流程:

调用 _pool.Create() 创建从属线程池(根据 SetThreadCount 设置的数量)。

启动主线程的事件循环 _baseloop.Start(),进入 “监控事件→处理事件→执行任务” 的无限循环。

SetThreadCount(int count):设置从属线程数量

void SetThreadCount(int count) { return _pool.SetThreadCount(count); }

作用:配置 LoopThreadPool 的工作线程数量(需在 Start() 前调用),用于负载均衡客户端连接。

连接管理(新连接建立与销毁)

NewConnection(int fd):处理新连接

void NewConnection(int fd)
{
_next_id++; // 生成新的连接ID
// 创建Connection对象,绑定线程池分配的EventLoop(负载均衡)
PtrConnection conn(new Connection(_pool.NextLoop(), _next_id, fd));
// 设置连接的各类回调(外部注册的业务逻辑)
conn->SetMessageCallback(_message_callback);
conn->SetClosedCallback(_closed_callback);
conn->SetConnectedCallback(_connected_callback);
conn->SetAnyEventCallback(_event_callback);
// 设置连接关闭时的服务器回调(从_conns中移除)
conn->SetSrvClosedCallback(std::bind(&TcpServer::RemoveConnection, this, std::placeholders::_1));
// 若启用非活跃销毁,设置超时时间
if (_enable_inactive_release)
conn->EnableInactiveRelease(_timeout);
conn->Established(); // 初始化连接(注册IO事件到对应EventLoop)
_conns.insert(std::make_pair(_next_id, conn)); // 加入连接管理哈希表
}

核心逻辑:当 Acceptor 接收到新客户端连接(获得 fd)时,创建 Connection 对象并初始化:
通过 _pool.NextLoop() 从线程池选择一个 EventLoop(负载均衡),绑定该连接的 IO 处理。

关联外部注册的回调(如连接建立后通知业务层)。

若启用非活跃销毁,设置超时检测(通过定时器实现)。

调用 conn->Established() 激活连接(将 socket 的可读事件注册到绑定的 EventLoop)。

RemoveConnection 与 RemoveConnectionInLoop:移除连接

void RemoveConnection(const PtrConnection &conn)
{
// 确保在主线程事件循环中执行移除操作(线程安全)
_baseloop.RunInLoop(std::bind(&TcpServer::RemoveConnectionInLoop, this, conn));
}
void RemoveConnectionInLoop(const PtrConnection &conn)
{
int id = conn->Id();
auto it = _conns.find(id);
if (it != _conns.end()) {
_conns.erase(it); // 从哈希表中移除连接
}
}

作用:当客户端连接关闭时,从 _conns 哈希表中移除该连接(释放资源)。

线程安全:通过 _baseloop.RunInLoop 确保移除操作在主线程执行(避免多线程操作哈希表的竞态条件)。

回调函数注册(业务逻辑接入)

服务器通过以下函数允许外部注册业务逻辑回调,实现 “业务与框架解耦”:

// 注册连接建立回调(如客户端连接成功后触发)
void SetConnectedCallback(const ConnectedCallback &cb) { _connected_callback = cb; }
// 注册消息接收回调(如收到客户端数据后触发)
void SetMessageCallback(const MessageCallback &cb) { _message_callback = cb; }
// 注册连接关闭回调(如客户端断开后触发)
void SetClosedCallback(const ClosedCallback &cb) { _closed_callback = cb; }
// 注册任意事件回调(如连接发生错误时触发)
void SetAnyEventCallback(const AnyEventCallback &cb) { _event_callback = cb; }

示例:外部可注册 MessageCallback 处理客户端发送的消息(如解析协议、执行业务逻辑)。

非活跃连接管理

void EnableInactiveRelease(int timeout)
{
_timeout = timeout;
_enable_inactive_release = true; // 启用非活跃连接销毁
}

作用:启用 “非活跃连接自动销毁” 功能,设置超时时间 timeout。当连接超过 timeout 未收发数据时,会触发自动关闭(由 Connection 内部定时器实现)。

定时任务接口

void RunAfter(const Functor &task, int delay)
{
_baseloop.RunInLoop(std::bind(&TcpServer::RunAfterInLoop, this, task, delay));
}
void RunAfterInLoop(const Functor &task, int delay)
{
_next_id++; // 生成定时任务ID
_baseloop.TimerAdd(_next_id, delay, task); // 添加到主线程定时器
}

作用:提供服务器级别的定时任务接口(如延迟 delay 秒后执行某个任务)。

实现:通过主线程 _baseloop 的定时器(TimerWheel)添加任务,确保定时逻辑在主线程执行。

其他辅助函数(Channel 和 TimerWheel 相关)

这些函数是框架内部组件的接口,用于事件管理和定时任务调度:

Channel 类的事件更新与移除

void Channel::Remove() { return _loop->RemoveEvent(this); } // 从Poller中移除事件监控
void Channel::Update() { return _loop->UpdateEvent(this); } // 向Poller添加/修改事件监控

作用:Channel 是文件描述符(fd)和事件回调的封装,通过 Update/Remove 通知 EventLoop 中的 Poller 更新监控状态(如注册 socket 的可读事件、移除关闭连接的监控)。

TimerWheel 类的定时任务接口

// 添加定时任务(确保在EventLoop线程执行)
void TimerWheel::TimerAdd(uint64_t id, uint32_t delay, const TaskFunc &cb)
{
_loop->RunInLoop(std::bind(&TimerWheel::TimerAddInLoop, this, id, delay, cb));
}
// 刷新定时任务(延长超时时间)
void TimerWheel::TimerRefresh(uint64_t id)
{
_loop->RunInLoop(std::bind(&TimerWheel::TimerRefreshInLoop, this, id));
}
// 取消定时任务
void TimerWheel::TimerCancel(uint64_t id)
{
_loop->RunInLoop(std::bind(&TimerWheel::TimerCancelInLoop, this, id));
}

作用:TimerWheel 的对外接口,通过 _loop->RunInLoop 确保所有定时任务操作在 EventLoop 线程执行(线程安全),避免多线程修改定时器状态。

整体工作流程(TcpServer 运行链路)

初始化:

创建 TcpServer 时,初始化 _acceptor 监听指定端口,注册新连接回调 NewConnection。

调用 SetThreadCount 设置从属线程数量(如 4 个工作线程)。

启动服务器:

Start() 调用 _pool.Create() 创建工作线程池,每个线程运行独立的 EventLoop。

启动主线程 _baseloop,进入事件循环,_acceptor 开始监控新连接。

处理新连接:

客户端连接到来时,_acceptor 触发 NewConnection,生成连接 ID 并创建 Connection 对象。

通过 _pool.NextLoop() 选择一个工作线程的 EventLoop 绑定该连接,注册 IO 事件。

运行时处理:

客户端发送数据时,对应 EventLoop 触发 Connection 的读事件,调用 _message_callback 处理业务。

连接关闭时,Connection 调用 RemoveConnection,从 _conns 中移除并释放资源。

若启用非活跃销毁,超时未活动的连接会被自动关闭。

定时任务:

外部通过 RunAfter 添加定时任务,由主线程 _baseloop 的 TimerWheel 调度执行。