Reactor设计模式及其在epoll中的应用

目录

一、Reactor模式的由来

二、Reactor模式的核心组件及工作流程

三、基础Reactor模式的接口设计

[1. 事件源定义](#1. 事件源定义)

[2. 事件处理器接口(EventHandler)](#2. 事件处理器接口(EventHandler))

[3. 事件多路分发器接口(EventDemultiplexer)](#3. 事件多路分发器接口(EventDemultiplexer))

[4. Reactor 核心类(Reactor)](#4. Reactor 核心类(Reactor))

四、示例代码

五、总结


一、Reactor模式的由来

在网络通信中,我们已经学过了使用epoll模型来帮助我们完成高并发场景下的网络通信问题,但是在使用epoll_wait后,就会发现有两种写法:第一种是以FD的类型为主要判断条件,第二类是以触发事件的类型为主要判断条件。在简单的场景中,二者都是完全合理的,但是人们发现随着代码的复杂度提高,第一种写法的臃肿程度逐渐变高,代码也不利于维护。这是因为,每次多增添一种FD类型,就要在里面插入一个if、else代码块;而在第二种场景下,由于事件始终只有那么几种:读、写、错误等。再多的FD类型也只是在这几个有限的if、else代码块中插入扩展。

我们把这种第一判断条件为事件类型的方式称为反应堆模式,本质上是把直观的思维模式,升级成更加抽象的事件驱动思维,用一种框架解决了稳定点和变化点的问题。于是逐渐成为了一种设计模式---Reactor模式。

Reactor 模式是一种事件驱动(Event-Driven)设计模式,它的核心是通过一个 "事件循环" 不断监听事件,当事件发生时自动调用对应的处理逻辑。这种模式特别适合处理多个并发事件源,能高效地将事件与处理逻辑解耦。

二、Reactor模式的核心组件及工作流程

Reactor模式的本质是"组件化的事件处理框架",其核心能力依赖于4个紧密协作的组件,我们用智能家居系统来类比,解释各个组件的作用:

事件源(Event Source)

产生事件的实体,是事件的源头。好比智能家居的传感器,对于环境温度变化产生事件

事件多路分发器(Event Demultiplexer):

监控多个事件源,等待事件发生并收集就绪事件的"监听器"。比如智能家居的中控器,当各个传感器产生事件的时候,会把事件告诉中控器。虽然他叫分发器,但是并不执行分发模块,仅仅是监控,类似于IO多路复用。

事件处理器:

定义事件处理接口,包含具体的业务逻辑。比如空调控制器、点灯控制器。中央控制器把事件按照类别分别发送给这些处理模块。

Reactor核心:

协调各个组件的总指挥,负责事件注册,事件分发,以及驱动事件循环。即提供一个运行框架,让上述三个组件能在框架中配合使用。注意:他还有个核心功能是分发事件。

组件协作工作流程:

(1)事件源被注册到Reactor核心,把某类事件关联到对应的事件处理器。

(2)Reactor核心将事件源移交给事件多路分发器监控。

(3)事件多路分发器等待事件发生。

(4)事件发生后,分发器将就绪事件返还给Reactor核心。

(5)Reactor核心根据事件源找到对应的处理器,调用事件处理逻辑。

三、基础Reactor模式的接口设计

为了让框架具备通用性和可扩展性,我们先抽象出核心接口。接口设计遵循依赖倒置原则:高层模块(Reactor 核心)依赖抽象接口,而非具体实现。

1. 事件源定义

首先定义事件的 "类型标识",用于区分不同事件(如可读、可写):

cpp 复制代码
// 事件类型枚举(基础版)
enum class EventType {
    EVENT_READ,  // 可读事件(数据到达、新连接等)
    EVENT_WRITE  // 可写事件(缓冲区空闲,可发送数据)
};

当然仅仅只有类型定义远远不够,需要有一个连接类对其封装。我们也把这个连接类称为事件源。

这个类是对fd的封装,当我们使用accept的时候,会得到一个新的文件描述符fd,为了将回调函数抽离出来后方便调用,而不是依赖于传参,我们把这个fd封装到一个类中。同时由于各个文件的缓冲区希望是独立的,否则会出现数据混淆(尤其是在并发场景下)。所以我们设计了两个收、发两个缓冲区。

这个类和处理器类有着紧密联系,一般情况下设计会让他们互相持有对方的指针。即连接类可以通过指针访问到处理器中的回调函数。而处理器在使用回调函数的时候也能方便地通过Connection类得到其fd及缓冲区等字段。

cpp 复制代码
//5.连接类组件:负责管理fd、收发缓冲区等
class Connection
{
private:
    int _fd=-1;
    std::vector<char> _recvBuffer;
    std::vector<char> _sendBuffer;
    EventType _type;

public:
    //构造函数
    explicit Connection(int fd)
    :_fd(fd)
    {
        _recvBuffer.reserve(1024);
        _sendBuffer.reserve(1024);
    }

    //析构函数
    ~Connection()
    {
        if(_fd!=-1)
        {
            close(_fd);
            _fd=-1;
        }
    }
    
    //让处理器获取fd
    int getfd()
    {
        return _fd;
    }
    //获取读缓冲区
    std::vector<char>& get_recvBuffer()
    {
        return _recvBuffer;
    }
    //获取写缓冲区
    std::vector<char>& get_sendBuffer()
    {
        return _sendBuffer;
    }

};

2. 事件处理器接口(EventHandler)

所有具体的事件处理器都需实现此接口,定义 "处理什么事件" 和 "关联哪个事件源":

cpp 复制代码
// 事件处理器接口:封装事件处理逻辑
class EventHandler {
public:
    // 纯虚函数:处理事件的核心逻辑
    // 参数:事件源的文件描述符、事件类型
    virtual void handleEvent(int fd, EventType type) = 0;
    
    // 纯虚函数:获取当前处理器关联的事件源fd
    // 作用:Reactor通过fd找到对应的处理器
    virtual int getFd() const = 0;
    
    // 虚析构函数:确保子类析构函数被正确调用
    virtual ~EventHandler() = default;
};

接口设计理由

  • handleEvent统一处理入口,无论处理文件还是网络事件,都通过此方法触发;
  • getFd绑定事件源,Reactor 通过 fd 建立 "事件源 - 处理器" 的映射关系。

3. 事件多路分发器接口(EventDemultiplexer)

cpp 复制代码
#include <vector>
#include <utility>  // 用于std::pair

// 事件多路分发器接口:定义事件监控、注册、移除的规范
class EventDemultiplexer {
public:
    // 等待事件就绪
    // 参数:timeout-超时时间(秒);activeEvents-输出参数,存储就绪事件(fd, 事件类型)
    // 返回值:就绪事件数量,-1表示错误
    virtual int waitEvents(int timeout, std::vector<std::pair<int, EventType>>& activeEvents) = 0;
    
    // 注册事件:将fd和事件类型加入监控
    virtual void registerEvent(int fd, EventType type) = 0;
    
    // 移除事件:停止监控fd的指定事件类型
    virtual void removeEvent(int fd, EventType type) = 0;
    
    virtual ~EventDemultiplexer() = default;
};

接口设计理由

  • waitEvents是核心方法,负责阻塞等待事件,返回后 Reactor 即可获取就绪事件;
  • registerEventremoveEvent支持动态添加 / 移除事件源,适应场景变化(如客户端连接 / 断开)。

4. Reactor 核心类(Reactor)

协调事件注册、分发和循环的核心控制器:

cpp 复制代码
#include <map>
#include <memory>  // 可选,用于管理指针

// Reactor核心类:事件驱动的总控制器
class Reactor {
private:
    EventDemultiplexer* demultiplexer;  // 事件分发器(依赖注入)
    std::map<int, EventHandler*> handlers;  // fd到处理器的映射表(核心映射)

public:
    // 构造函数:传入具体的事件分发器(依赖注入,方便替换select/epoll)
    explicit Reactor(EventDemultiplexer* demux) : demultiplexer(demux) {}

    // 注册事件:将事件源、事件类型与处理器关联
    void registerHandler(EventHandler* handler, EventType type) {
        int fd = handler->getFd();
        handlers[fd] = handler;  // 记录fd与处理器的映射
        demultiplexer->registerEvent(fd, type);  // 通知分发器开始监控
    }

    // 移除事件:停止监控并解除映射
    void removeHandler(EventHandler* handler, EventType type) {
        int fd = handler->getFd();
        demultiplexer->removeEvent(fd, type);  // 通知分发器停止监控
        handlers.erase(fd);  // 移除映射关系
    }

    // 事件循环:Reactor的核心运行逻辑
    void eventLoop() {
        while (true) {  // 无限循环,持续处理事件
            std::vector<std::pair<int, EventType>> activeEvents;  // 存储就绪事件
            // 等待事件就绪(超时1秒,避免永久阻塞)
            int n = demultiplexer->waitEvents(1, activeEvents);
            if (n < 0) {  // 错误处理
                perror("waitEvents error");
                break;
            } else if (n == 0) {  // 超时,无事件就绪
                continue;
            }

            // 遍历所有就绪事件,调用对应处理器处理
            for (const auto& [fd, type] : activeEvents) {
                auto it = handlers.find(fd);
                if (it != handlers.end()) {  // 确保处理器存在
                    it->second->handleEvent(fd, type);  // 分发事件给处理器
                }
            }
        }
    }
};

核心逻辑解析

  • handlers映射表是 Reactor 的 "大脑",通过 fd 快速找到对应的处理器;
  • eventLoop是 "心脏",不断循环等待事件→收集事件→分发事件,构成事件驱动的核心流程。

四、示例代码

cpp 复制代码
#include <sys/epoll.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <errno.h>
#include <cstring>
#include <vector>
#include <map>
#include <memory>
#include <functional>
#include <iostream>
#include <chrono>
#include <ctime>

// 事件类型枚举
enum class EventType
{
    EVENT_READ = EPOLLIN,
    EVENT_WRITE = EPOLLOUT,
    EVENT_ERROR = EPOLLERR
};

// 事件触发模式
enum class TriggerMode
{
    LEVEL_TRIGGER,
    EDGE_TRIGGER
};

// 前向声明
class Reactor;

// 工具函数:获取当前时间字符串(用于日志)
std::string getCurrentTime() {
    auto now = std::chrono::system_clock::now();
    std::time_t now_time = std::chrono::system_clock::to_time_t(now);
    return std::ctime(&now_time);
}

// 1. 连接管理类
class Connection
{
private:
    int _fd;
    std::vector<char> _recvBuffer;
    std::vector<char> _sendBuffer;
    TriggerMode _triggerMode;

public:
    // 读取数据到缓冲区
    ssize_t readData()
    {
        char buffer[1024];
        ssize_t n;
        ssize_t total = 0;

        //因为有可能设置为边沿触发,所以有可能一次性读不完。需要循环读。
        //即使为水平触发,没读完会多次通知事件就绪,但是也导致了重复唤醒的开销。所以无论ET、LT都要用循环读
        while (true)
        {
            n = read(_fd, buffer, sizeof(buffer));
            if (n > 0)
            {
                _recvBuffer.insert(_recvBuffer.end(), buffer, buffer + n);
                total += n;
                std::cout << "[" << getCurrentTime() << "] Connection " << _fd 
                          << " read " << n << " bytes (total: " << total << ")" << std::endl;

                // 边缘触发模式下,数据小于缓冲区大小时退出循环
                if (_triggerMode == TriggerMode::EDGE_TRIGGER && n < sizeof(buffer))
                {
                    break;
                }
            }
            else if (n == 0)
            {
                std::cout << "[" << getCurrentTime() << "] Connection " << _fd << " closed by client" << std::endl;
                return 0;
            }
            else
            {
                // 非阻塞模式下无数据可读,正常退出
                if (errno == EAGAIN || errno == EWOULDBLOCK)
                { 
                    break;
                }
                //其他情况说明发生错误了
                else
                {
                    std::cerr << "[" << getCurrentTime() << "] Connection " << _fd 
                              << " read error: " << strerror(errno) << std::endl;
                    return -1;
                }
            }
        }
        return total;
    }

    // 从缓冲区发送数据
    ssize_t sendData()
    {
        if (_sendBuffer.empty())
        {
            return 0;
        }

        //因为send函数是把用户空间数据拷贝到内核态缓冲区(skb缓冲区队列),一般情况下都是可以一次性拷贝的。所以不需要循环写
        //一旦内核的缓冲区队列满了,则返回值n<0
        ssize_t n = send(_fd, _sendBuffer.data(), _sendBuffer.size(), 0);
        if (n > 0)
        {
            std::cout << "[" << getCurrentTime() << "] Connection " << _fd 
                      << " sent " << n << " bytes" << std::endl;
            _sendBuffer.erase(_sendBuffer.begin(), _sendBuffer.begin() + n);
        }
        else if (n == 0)
        {
            std::cout << "[" << getCurrentTime() << "] Connection " << _fd << " send 0 bytes" << std::endl;
            return 0;
        }
        //返回值小于0说明缓冲区无空间,此时需要判断是真的没空间还是发生错误了。
        else
        {
            if (errno == EAGAIN || errno == EWOULDBLOCK)
            {
                std::cout << "[" << getCurrentTime() << "] Connection " << _fd 
                          << " send buffer full, will retry" << std::endl;
                return 0;
            }
            else
            {
                std::cerr << "[" << getCurrentTime() << "] Connection " << _fd 
                          << " send error: " << strerror(errno) << std::endl;
                return -1;
            }
        }

        return n;
    }

    // 常用访问函数
    int getFd() const { return _fd; }
    std::vector<char>& getRecvBuffer() { return _recvBuffer; }
    std::vector<char>& getSendBuffer() { return _sendBuffer; }
    TriggerMode getTriggerMode() const { return _triggerMode; }

    // 构造函数
    explicit Connection(int fd, TriggerMode mode = TriggerMode::LEVEL_TRIGGER)
        : _fd(fd), _triggerMode(mode)
    {
        _recvBuffer.reserve(4096);
        _sendBuffer.reserve(4096);
        
        // 设置非阻塞模式
        int flags = fcntl(_fd, F_GETFL, 0);
        if (flags == -1)
        {
            std::cerr << "[" << getCurrentTime() << "] fcntl GETFL error: " << strerror(errno) << std::endl;
        }
        else if (fcntl(_fd, F_SETFL, flags | O_NONBLOCK) == -1)
        {
            std::cerr << "[" << getCurrentTime() << "] fcntl SETFL error: " << strerror(errno) << std::endl;
        }
        
        std::cout << "[" << getCurrentTime() << "] Connection " << _fd << " created (mode: " 
                  << (mode == TriggerMode::LEVEL_TRIGGER ? "LT" : "ET") << ")" << std::endl;
    }

    // 析构函数
    ~Connection()
    {
        if (_fd != -1)
        {
            std::cout << "[" << getCurrentTime() << "] Connection " << _fd << " closed" << std::endl;
            close(_fd);
            _fd = -1;
        }
    }

    // 禁用拷贝
    Connection(const Connection&) = delete;
    Connection& operator=(const Connection&) = delete;

    // 移动构造
    Connection(Connection&& other) noexcept
        : _fd(other._fd)
        , _recvBuffer(std::move(other._recvBuffer))
        , _sendBuffer(std::move(other._sendBuffer))
        , _triggerMode(other._triggerMode)
    {
        other._fd = -1;
    }
};

// 2. 事件处理器接口
class EventHandler
{
protected:
    std::unique_ptr<Connection> _connection;

public:
    int getFd() const { return _connection->getFd(); }

    //这里因为使用了智能指针unique_ptr所以要用get函数获取原生指针
    Connection* getConnection() { return _connection.get(); }
    
    // 事件处理接口
    virtual void handleRead() = 0;
    virtual void handleWrite() = 0;
    virtual void handleError() = 0;

    // 构造函数
    explicit EventHandler(std::unique_ptr<Connection> conn)
        : _connection(std::move(conn))
    {
        std::cout << "[" << getCurrentTime() << "] EventHandler created for fd: " << getFd() << std::endl;
    }
    
    // 析构函数
    virtual ~EventHandler()
    {
        std::cout << "[" << getCurrentTime() << "] EventHandler destroyed for fd: " << getFd() << std::endl;
    }

    // 禁用拷贝
    EventHandler(const EventHandler&) = delete;
    EventHandler& operator=(const EventHandler&) = delete;
};

// 3. 事件多路分发器接口
class EventDemultiplexer 
{
public:
    virtual int waitEvents(int timeout, std::vector<std::pair<int, EventType>>& activeEvents) = 0;
    virtual void registerEvent(int fd, EventType type) = 0;
    virtual void registerEvent(int fd, EventType type, TriggerMode mode) = 0;
    virtual void removeEvent(int fd, EventType type) = 0;
    virtual ~EventDemultiplexer() = default;
};

// 4. epoll事件多路分发器
class EpollDemultiplexer : public EventDemultiplexer
{
private:
    int _epollfd;
    static const int MAX_EVENTS = 1024;
    epoll_event _events[MAX_EVENTS];

public:
    // 等待事件就绪
    int waitEvents(int timeout, std::vector<std::pair<int, EventType>>& activeEvents) override
    {
        activeEvents.clear();
        int nfds = epoll_wait(_epollfd, _events, MAX_EVENTS, timeout);
        
        if (nfds == -1)
        {
            if (errno == EINTR)
            {
                // 被信号中断,返回0表示无事件
                return 0;
            }
            std::cerr << "[" << getCurrentTime() << "] epoll_wait error: " << strerror(errno) << std::endl;
            return -1;
        }

        // 解析事件
        for (int i = 0; i < nfds; i++)
        {
            int fd = _events[i].data.fd;
            uint32_t epoll_event = _events[i].events;

            if (epoll_event & EPOLLIN)
            {
                activeEvents.emplace_back(fd, EventType::EVENT_READ);
            }
            if (epoll_event & EPOLLOUT)
            {
                activeEvents.emplace_back(fd, EventType::EVENT_WRITE);
            }
            if (epoll_event & EPOLLERR)
            {
                activeEvents.emplace_back(fd, EventType::EVENT_ERROR);
            }
        }

        std::cout << "[" << getCurrentTime() << "] epoll_wait returned " << nfds << " events" << std::endl;
        return nfds;
    }

    // 注册事件(默认水平触发)
    void registerEvent(int fd, EventType type) override
    {
        registerEvent(fd, type, TriggerMode::LEVEL_TRIGGER);
    }

    // 注册事件(带触发模式)
    void registerEvent(int fd, EventType type, TriggerMode mode) override
    {
        epoll_event event{};
        event.data.fd = fd;
        event.events = static_cast<uint32_t>(type);
        
        if (mode == TriggerMode::EDGE_TRIGGER)
        {
            event.events |= EPOLLET;
        }

        // 先尝试修改事件,失败则添加
        if (epoll_ctl(_epollfd, EPOLL_CTL_MOD, fd, &event) == -1)
        {
            if (errno == ENOENT)
            {
                // 事件不存在,添加新事件
                if (epoll_ctl(_epollfd, EPOLL_CTL_ADD, fd, &event) == -1)
                {
                    std::cerr << "[" << getCurrentTime() << "] epoll_ctl ADD error (fd=" << fd 
                              << "): " << strerror(errno) << std::endl;
                    return;
                }
                std::cout << "[" << getCurrentTime() << "] epoll added event for fd: " << fd << std::endl;
            }
            else
            {
                std::cerr << "[" << getCurrentTime() << "] epoll_ctl MOD error (fd=" << fd 
                          << "): " << strerror(errno) << std::endl;
                return;
            }
        }
        else
        {
            std::cout << "[" << getCurrentTime() << "] epoll modified event for fd: " << fd << std::endl;
        }
    }

    // 移除事件
    void removeEvent(int fd, EventType type) override
    {
        epoll_event event{};
        event.data.fd = fd;
        event.events = static_cast<uint32_t>(type);

        if (epoll_ctl(_epollfd, EPOLL_CTL_DEL, fd, &event) == -1)
        {
            if (errno != ENOENT)
            {
                std::cerr << "[" << getCurrentTime() << "] epoll_ctl DEL error (fd=" << fd 
                          << "): " << strerror(errno) << std::endl;
            }
            else
            {
                std::cout << "[" << getCurrentTime() << "] epoll event for fd " << fd << " not found, ignoring" << std::endl;
            }
        }
        else
        {
            std::cout << "[" << getCurrentTime() << "] epoll removed event for fd: " << fd << std::endl;
        }
    }

    // 构造函数
    EpollDemultiplexer()
    {
        // 使用epoll_create1更安全,设置EPOLL_CLOEXEC标志
        _epollfd = epoll_create1(EPOLL_CLOEXEC);
        if (_epollfd == -1)
        {
            std::cerr << "[" << getCurrentTime() << "] epoll_create1 error: " << strerror(errno) << std::endl;
            exit(EXIT_FAILURE);
        }
        std::cout << "[" << getCurrentTime() << "] EpollDemultiplexer created (epollfd=" << _epollfd << ")" << std::endl;
    }

    // 析构函数
    ~EpollDemultiplexer() override
    {
        if (_epollfd != -1)
        {
            std::cout << "[" << getCurrentTime() << "] Closing epollfd: " << _epollfd << std::endl;
            close(_epollfd);
            _epollfd = -1;
        }
    }
};

// 5. Reactor核心
class Reactor
{
private:
    std::unique_ptr<EventDemultiplexer> _demultiplexer;
    std::map<int, std::unique_ptr<EventHandler>> _handlers;
    bool _isrunning;

public:
    // 构造函数
    explicit Reactor(std::unique_ptr<EventDemultiplexer> demux)
        : _demultiplexer(std::move(demux)), _isrunning(false)
    {
        std::cout << "[" << getCurrentTime() << "] Reactor created" << std::endl;
    }

    // 注册新的事件处理器
    void registerHandler(std::unique_ptr<EventHandler> handler, EventType type)
    {
        int fd = handler->getFd();
        std::cout << "[" << getCurrentTime() << "] Registering handler for fd: " << fd << std::endl;
        
        // 存储处理器到内核中
        _handlers[fd] = std::move(handler);
        
        // 注册事件到分发器中
        auto conn = _handlers[fd]->getConnection();
        auto epollDemux = dynamic_cast<EpollDemultiplexer*>(_demultiplexer.get());
        if (epollDemux)
        {
            epollDemux->registerEvent(fd, type, conn->getTriggerMode());
        }
        else
        {
            _demultiplexer->registerEvent(fd, type);
        }
    }


    /*
   */

    // 更新事件类型(关键修复:不转移所有权,只更新事件)
    void updateHandler(int fd, EventType type)
    {
        auto it = _handlers.find(fd);
        if (it == _handlers.end())
        {
            std::cerr << "[" << getCurrentTime() << "] Update handler failed: fd " << fd << " not found" << std::endl;
            return;
        }

        std::cout << "[" << getCurrentTime() << "] Updating handler for fd " << fd << " to event type: " 
                  << (type == EventType::EVENT_READ ? "READ" : "WRITE") << std::endl;
        
        auto conn = it->second->getConnection();
        auto epollDemux = dynamic_cast<EpollDemultiplexer*>(_demultiplexer.get());
        if (epollDemux)
        {
            epollDemux->registerEvent(fd, type, conn->getTriggerMode());
        }
        else
        {
            _demultiplexer->registerEvent(fd, type);
        }
    }

    // 移除事件处理器
    void removeHandler(int fd)
    {
        if (_handlers.count(fd))
        {
            std::cout << "[" << getCurrentTime() << "] Removing handler for fd: " << fd << std::endl;
            
            // 从分发器中移除所有事件
            _demultiplexer->removeEvent(fd, EventType::EVENT_READ);
            _demultiplexer->removeEvent(fd, EventType::EVENT_WRITE);
            _demultiplexer->removeEvent(fd, EventType::EVENT_ERROR);
            
            // 从核心中移除处理器
            _handlers.erase(fd);
        }
        else
        {
            std::cout << "[" << getCurrentTime() << "] Remove handler failed: fd " << fd << " not found" << std::endl;
        }
    }

    // 获取事件处理器
    EventHandler* getHandler(int fd)
    {
        auto it = _handlers.find(fd);
        return (it != _handlers.end()) ? it->second.get() : nullptr;
    }

    // 启动事件循环
    void start()
    {
        if (_isrunning)
        {
            std::cout << "[" << getCurrentTime() << "] Reactor already running" << std::endl;
            return;
        }
        
        _isrunning = true;
        std::cout << "[" << getCurrentTime() << "] Reactor starting event loop" << std::endl;
        eventloop();
    }

    // 停止事件循环
    void stop()
    {
        _isrunning = false;
        std::cout << "[" << getCurrentTime() << "] Reactor stopping event loop" << std::endl;
    }

private:
    // 事件循环
    void eventloop()
    {
        while (_isrunning)
        {
            std::vector<std::pair<int, EventType>> activeEvents;
            int n = _demultiplexer->waitEvents(1000, activeEvents);

            if (n < 0)
            {
                std::cerr << "[" << getCurrentTime() << "] Event loop error, stopping" << std::endl;
                break;
            }

            // 处理就绪事件
            for (const auto& [fd, type] : activeEvents)
            {
                EventHandler* handler = getHandler(fd);
                if (!handler)
                {
                    std::cerr << "[" << getCurrentTime() << "] No handler found for fd: " << fd << std::endl;
                    continue;
                }

                try
                {
                    switch (type)
                    {
                        case EventType::EVENT_READ:
                            std::cout << "[" << getCurrentTime() << "] Handling READ event for fd: " << fd << std::endl;
                            handler->handleRead();
                            break;
                        case EventType::EVENT_WRITE:
                            std::cout << "[" << getCurrentTime() << "] Handling WRITE event for fd: " << fd << std::endl;
                            handler->handleWrite();
                            break;
                        case EventType::EVENT_ERROR:
                            std::cout << "[" << getCurrentTime() << "] Handling ERROR event for fd: " << fd << std::endl;
                            handler->handleError();
                            removeHandler(fd);
                            break;
                    }
                }
                catch (const std::exception& e)
                {
                    std::cerr << "[" << getCurrentTime() << "] Error handling event for fd " << fd 
                              << ": " << e.what() << std::endl;
                    removeHandler(fd);
                }
            }
        }
    }
};

// 6. 具体事件处理器实现
// 连接处理器(处理已建立连接的读写)
class ConnectionHandler : public EventHandler {
private:
    Reactor* _reactor;

public:
    ConnectionHandler(std::unique_ptr<Connection> conn, Reactor* reactor)
        : EventHandler(std::move(conn)), _reactor(reactor) {}

    void handleRead() override {
        auto conn = getConnection();
        ssize_t n = conn->readData();
        
        if (n <= 0) {
            // 连接关闭或错误,移除处理器
            _reactor->removeHandler(getFd());
            return;
        }

        // 简单回声逻辑:将接收的数据放入发送缓冲区
        auto& recvBuf = conn->getRecvBuffer();
        auto& sendBuf = conn->getSendBuffer();
        sendBuf.insert(sendBuf.end(), recvBuf.begin(), recvBuf.end());
        std::cout << "[" << getCurrentTime() << "] Connection " << getFd() 
                  << " echoing " << recvBuf.size() << " bytes" << std::endl;
        recvBuf.clear();

        /*
        这里非常关键,在之前我们的代码逻辑是注册写事件,调用的是registerHandler函数,而这个函数使用的是移动赋值。_handler[fd]=std::move(handler)
        即将现在的处理器类移动给了Reactor核心,但是我们reactor在获得新连接,创建Connection的时候已经创建了处理器类,核心中的unique_ptr已经有指向
        此时调用rigisterHandler又创建了一个unique_ptr,然后将第二个指针移动赋值给了核心。
        问题出现了:核心中的unique_ptr和这里临时创建的unique_ptr都指向同一个处理器类。当智能指针声明周期结束的时候,两次析构,程序崩溃。
        */
       //我们由此也明白一个关键道理:
       //处理读事件后,修改监控事件为写事件;处理写事件后,修改监控事件为读事件。而不是重新注册事件
        //体现一个轮转性

        // 关键修复:使用updateHandler更新事件类型,不转移所有权
        _reactor->updateHandler(getFd(), EventType::EVENT_WRITE);
    }

    void handleWrite() override {
        auto conn = getConnection();
        ssize_t n = conn->sendData();
        
        if (n < 0) {
            // 发送错误,移除处理器
            _reactor->removeHandler(getFd());
            return;
        }

        // 发送完成后,重新注册读事件(保持连接)
        if (conn->getSendBuffer().empty()) {
            std::cout << "[" << getCurrentTime() << "] Connection " << getFd() 
                      << " send complete, waiting for new data" << std::endl;
            _reactor->updateHandler(getFd(), EventType::EVENT_READ);
        }
        // 未发送完成会继续触发写事件(epoll默认行为)
    }

    void handleError() override {
        std::cerr << "[" << getCurrentTime() << "] Connection " << getFd() << " error occurred" << std::endl;
    }
};

// 监听处理器(处理新连接)
class AcceptorHandler : public EventHandler {
private:
    Reactor* _reactor;
    TriggerMode _triggerMode;

public:
    AcceptorHandler(std::unique_ptr<Connection> conn, Reactor* reactor, TriggerMode mode)
        : EventHandler(std::move(conn)), _reactor(reactor), _triggerMode(mode) {}

    void handleRead() override {
        struct sockaddr_in clientAddr;
        socklen_t clientLen = sizeof(clientAddr);
        int clientFd = accept(getFd(), (struct sockaddr*)&clientAddr, &clientLen);
        
        if (clientFd == -1) {
            std::cerr << "[" << getCurrentTime() << "] Accept error: " << strerror(errno) << std::endl;
            return;
        }

        // 打印新连接信息
        std::cout << "[" << getCurrentTime() << "] New connection from " 
                  << inet_ntoa(clientAddr.sin_addr) << ":" << ntohs(clientAddr.sin_port) 
                  << " (fd=" << clientFd << ")" << std::endl;

        // 创建新连接处理器并注册
        auto conn = std::make_unique<Connection>(clientFd, _triggerMode);
        auto handler = std::make_unique<ConnectionHandler>(std::move(conn), _reactor);
        _reactor->registerHandler(std::move(handler), EventType::EVENT_READ);
    }

    void handleWrite() override {
        // 监听套接字通常不处理写事件
        std::cout << "[" << getCurrentTime() << "] Unexpected WRITE event on listener fd: " << getFd() << std::endl;
    }

    void handleError() override {
        std::cerr << "[" << getCurrentTime() << "] Listener fd " << getFd() << " error occurred" << std::endl;
    }
};

// 主函数
int main() {
    // 创建监听套接字
    int listenFd = socket(AF_INET, SOCK_STREAM, 0);
    if (listenFd == -1) {
        std::cerr << "[" << getCurrentTime() << "] socket creation failed: " << strerror(errno) << std::endl;
        return 1;
    }

    // 设置端口复用
    int opt = 1;
    if (setsockopt(listenFd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1) {
        std::cerr << "[" << getCurrentTime() << "] setsockopt failed: " << strerror(errno) << std::endl;
        close(listenFd);
        return 1;
    }

    // 绑定地址
    struct sockaddr_in serverAddr;
    memset(&serverAddr, 0, sizeof(serverAddr));
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_addr.s_addr = INADDR_ANY;
    serverAddr.sin_port = htons(8080);
    
    if (bind(listenFd, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) == -1) {
        std::cerr << "[" << getCurrentTime() << "] bind failed: " << strerror(errno) << std::endl;
        close(listenFd);
        return 1;
    }

    // 开始监听
    if (listen(listenFd, SOMAXCONN) == -1) {
        std::cerr << "[" << getCurrentTime() << "] listen failed: " << strerror(errno) << std::endl;
        close(listenFd);
        return 1;
    }

    std::cout << "[" << getCurrentTime() << "] Server listening on port 8080 (fd=" << listenFd << ")" << std::endl;

    // 初始化Reactor
    auto demultiplexer = std::make_unique<EpollDemultiplexer>();
    Reactor reactor(std::move(demultiplexer));

    // 创建并注册Acceptor(使用水平触发模式)
    auto conn = std::make_unique<Connection>(listenFd, TriggerMode::LEVEL_TRIGGER);
    auto acceptor = std::make_unique<AcceptorHandler>(std::move(conn), &reactor, TriggerMode::LEVEL_TRIGGER);
    reactor.registerHandler(std::move(acceptor), EventType::EVENT_READ);

    // 启动事件循环
    reactor.start();

    return 0;
}
    

五、总结

Reactor设计模式是一种常见的设计模式,他把各个模块解耦,提高了代码的稳定性和可扩展性。而网络epoll则天然适配Reactor模式,因为Reactor模式是一种事件驱动的设计模式,通过事件循环机制高效处理并发事件。这与网络epoll模型不谋而合。

其核心包含事件源、多路分发器、事件处理器和Reactor协调器四个组件,工作流程包括事件注册、监控、分发和处理。该模式采用接口化设计,定义事件类型、处理器接口、分发器接口等抽象层,实现稳定点与变化点的解耦。在网络编程中,Reactor模式与epoll机制天然适配,通过封装连接类管理文件描述符和缓冲区,有效提升代码的可维护性和扩展性。该模式将直观的FD类型判断转化为抽象的事件驱动处理,显著降低了复杂系统的代码臃肿度。

相关推荐
多吃蔬菜!!!7 分钟前
vscode 搭建C/C++开发环境搭建(linux)
linux·c语言·c++
李李李li16 分钟前
Ubuntu 22.04 安装tensorrt
linux·tensorrt
phoenix09812 小时前
Linux入门DAY29
linux·运维
小指纹2 小时前
河南萌新联赛2025第(六)场:郑州大学
java·开发语言·数据结构·c++·算法
一休哥助手2 小时前
Naive RAG:简单而高效的检索增强生成架构解析与实践指南
运维·人工智能·架构
叔叔别拉了我害怕2 小时前
封装FTPSClient连接ftps服务器
服务器·git·github
入秋2 小时前
Linux服务器安装部署 Nginx、Redis、PostgreSQL、Docker
linux·前端
不甘懦弱3 小时前
阿里云搭建flask服务器
服务器·python·flask
Bi3 小时前
包含多个子项目集成一个项目部署Vercel方法
运维·前端
岁忧3 小时前
(nice!!!)(LeetCode 每日一题) 1277. 统计全为 1 的正方形子矩阵 (动态规划)
java·c++·算法·leetcode·矩阵·go·动态规划