• 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. 添加任务!

    三、代码

    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(); 
            }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
  • 相关阅读:
    将java装进u盘指南
    数字孪生政务丨构建大数据可视化展现平台,提高行政服务效能
    蓝桥杯第四场双周赛(1~6)
    (六)centos7案例实战——sonarQube安装及springboot项目集成sonarQube完成代码质量检查
    照片太大怎么缩小kb?
    Chapter 02 - Let's Get Started(C#篇)
    TensorFlow深度学习!构建神经网络预测股票价格!⛵
    Kotlin 数据类(Data Class)
    【SpringCloud微服务项目实战-mall4cloud项目(2)】——mall4cloud-gateway
    vue如何实现2个新标签之间的信息共享
  • 原文地址:https://blog.csdn.net/weixin_54447296/article/details/133829919