1.13.C++项目:仿muduo库实现并发服务器之TcpServer模块的设计

文章目录

一、LoopThreadPool模块

TcpServer模块: 对所有模块的整合,通过 tcpserver 模块实例化的对象,可以非常简单的完成一个服务器的搭建。
对前面所有子模块的整合模块,提供给用户用于搭建一个高性能服务器的模块!

二、实现思想

(一)管理

  1. Acceptor对象,创建一个监听套接字!
  2. EventLoop 对象,baseloop对象,实现对监听套接字的事件监控!
  3. std::vector conns,实现对新建连接的管理!
  4. EventLoopPool 对象,创建loop线程池,对新建连接进行事件监控和处理!

(二)流程

流程:

  1. 在TcpServer中实例一个Acceptor对象,以及一个EventLoop 对象(baseloop)

  2. 将Acceptor 挂在baseloop 进行事件监控

  3. 一旦Acceptor 对象就绪了可读事件,则执行时间回调函数获取新建连接!

  4. 对新连接,创造一个 Connection 进行管理!

  5. 对新连接对应的 Connection 设置功能回调 (连接完成回调,消息回调,关闭回调,任意事件监控!)

  6. 启动Connettion 的非活跃链接的超时销毁功能

  7. 将新连接对应的Connection 挂到 LoopThreadPool 中的丛书线程对应的Eventloop 中进行事件监控!

  8. 一旦Connection对应的链接就绪了可读事件,则这个时候执行读事件回调函数,读取数据,读取完毕后调用TcpServer设置的消息回调!

(三)功能设计

  1. 设置从属线程池数量!
    2. 启动服务器
    3. 设置各种回调函数!(连接建立完成,消息,关闭,任意) 用户设置给TcpServer TcpServer设置获取的新连接!
    4. 是否启动非活跃连接超时销毁功能
    5. 添加任务!

三、代码

cpp 复制代码
class TcpServer {
    private:
        uint64_t _next_id;      //这是一个自动增长的连接ID,
        int _port;
        int _timeout;           //这是非活跃连接的统计时间---多长时间无通信就是非活跃连接
        bool _enable_inactive_release;//是否启动了非活跃连接超时销毁的判断标志
        EventLoop _baseloop;    //这是主线程的EventLoop对象,负责监听事件的处理
        Acceptor _acceptor;    //这是监听套接字的管理对象
        LoopThreadPool _pool;   //这是从属EventLoop线程池
        std::unordered_map<uint64_t, PtrConnection> _conns;//保存管理所有连接对应的shared_ptr对象

        using ConnectedCallback = std::function<void(const PtrConnection&)>;
        using MessageCallback = std::function<void(const PtrConnection&, Buffer *)>;
        using ClosedCallback = std::function<void(const PtrConnection&)>;
        using AnyEventCallback = std::function<void(const PtrConnection&)>;
        using Functor = std::function<void()>;
        ConnectedCallback _connected_callback;
        MessageCallback _message_callback;
        ClosedCallback _closed_callback;
        AnyEventCallback _event_callback;
    private:
        void RunAfterInLoop(const Functor &task, int delay) {
            _next_id++;
            _baseloop.TimerAdd(_next_id, delay, task);
        }
        //为新连接构造一个Connection进行管理
        void NewConnection(int fd) {
            _next_id++;
            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);
            conn->SetSrvClosedCallback(std::bind(&TcpServer::RemoveConnection, this, std::placeholders::_1));
            if (_enable_inactive_release) conn->EnableInactiveRelease(_timeout);//启动非活跃超时销毁
            conn->Established();//就绪初始化
            _conns.insert(std::make_pair(_next_id, conn));
        }
        void RemoveConnectionInLoop(const PtrConnection &conn) {
            int id = conn->Id();
            auto it = _conns.find(id);
            if (it != _conns.end()) {
                _conns.erase(it);
            }
        }
        //从管理Connection的_conns中移除连接信息
        void RemoveConnection(const PtrConnection &conn) {
            _baseloop.RunInLoop(std::bind(&TcpServer::RemoveConnectionInLoop, this, conn));
        }
    public:
        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上
        }
        void SetThreadCount(int count) { 
            return _pool.SetThreadCount(count); 
        }
        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; 
        }
        void EnableInactiveRelease(int timeout) { 
            _timeout = timeout; _enable_inactive_release = true; 
        }
        //用于添加一个定时任务
        void RunAfter(const Functor &task, int delay) {
            _baseloop.RunInLoop(std::bind(&TcpServer::RunAfterInLoop, this, task, delay));
        }
        void Start() { 
            _pool.Create(); 
            _baseloop.Start(); 
        }
};
相关推荐
白总Server5 分钟前
物联网网关确保设备安全
服务器·网络·物联网·安全·web安全·自然语言处理·架构
weixi_kelaile52012 分钟前
ai智能语音电销机器人可以做哪些事情?
java·linux·服务器·人工智能·机器人·云计算·腾讯云
qing_04060321 分钟前
C++——string的模拟实现(上)
开发语言·c++·string
我不会JAVA!1 小时前
排序算法(3) C++
c++·算法·排序算法
0725游广川3 小时前
cjson内存泄漏问题注意事项
服务器·json
Ddddddd_1585 小时前
C++ | Leetcode C++题解之第504题七进制数
c++·leetcode·题解
J_z_Yang5 小时前
LeetCode 202 - 快乐数
c++·算法·leetcode
加载中loading...6 小时前
Linux线程安全(二)条件变量实现线程同步
linux·运维·服务器·c语言·1024程序员节
安科瑞刘鸿鹏6 小时前
校园建筑用电安全监测装置 电气火灾监测预防设备功能介绍
运维·服务器·网络·嵌入式硬件·安全·能源
课堂随想6 小时前
【libGL error】Autodl云服务器配置ACT的conda虚拟环境生成训练数据时,遇到了libGL相关错误,涉及swrast_dri.so
运维·服务器·conda