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(); 
        }
};
相关推荐
秋名山小桃子4 分钟前
Kunlun 2280服务器(ARM)Raid卡磁盘盘符漂移问题解决
运维·服务器
与君共勉121385 分钟前
Nginx 负载均衡的实现
运维·服务器·nginx·负载均衡
努力学习的小廉11 分钟前
深入了解Linux —— make和makefile自动化构建工具
linux·服务器·自动化
MZWeiei15 分钟前
Zookeeper基本命令解析
大数据·linux·运维·服务器·zookeeper
小俊俊的博客29 分钟前
海康RGBD相机使用C++和Opencv采集图像记录
c++·opencv·海康·rgbd相机
Arenaschi34 分钟前
在Tomcat中部署应用时,如何通过域名访问而不加端口号
运维·服务器
小张认为的测试35 分钟前
Linux性能监控命令_nmon 安装与使用以及生成分析Excel图表
linux·服务器·测试工具·自动化·php·excel·压力测试
waicsdn_haha42 分钟前
Java/JDK下载、安装及环境配置超详细教程【Windows10、macOS和Linux图文详解】
java·运维·服务器·开发语言·windows·后端·jdk
_WndProc44 分钟前
C++ 日志输出
开发语言·c++·算法
薄荷故人_1 小时前
从零开始的C++之旅——红黑树及其实现
数据结构·c++