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

news/2024/7/5 2:04:11

文章目录

  • 一、LoopThreadPool模块
  • 二、实现思想
    • (一)管理
    • (二)流程
    • (三)功能设计
  • 三、代码

一、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(); 
        }
};

http://lihuaxi.xjx100.cn/news/1619075.html

相关文章

java+springboot+vue高校毕业生就业统计管理系统022xr

系统的设计与实现采用Spring、SpringMVC和MyBatis作为主体框架,系统设计遵循界面层、业务逻辑层和数据访问层的Web开发三层架构。采用B/S结构,使得系统更加容易维护。系统的设计与实现主要实现角色有管理员和用户,管理员在后台管理用户表模块、token表模块、生源信息模块、招聘…

【数据库系统概论】第四章数据库安全性

数据库的安全性&#xff1a;保护数据库以防止不合法使用所造成的数据泄露、更改或破坏 grant和revoke语法

3.6 Android gpu_mem ebpf程序设计原理(二)

本篇我们继续以gpu_mem为例详细拆解eBPF程序组成。 三,DEFINE_BPF_PROG宏 从宏的字面意义上,我们可以看到,该宏定义了处理kernel内核事件被触发后的handler函数。这部分后面照葫芦画瓢写HelloWorld Demo的时候还会介绍。这里我们来先看android的宏定义的设计。 framework…

【音视频|ALSA】SS528开发板编译Linux内核ALSA驱动、移植alsa-lib、采集与播放usb耳机声音

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…

二十三、【五种图层】

文章目录 像素图层智能图层文字图层形状图层调整图层 像素图层 像素图层由空白像素图层组成&#xff0c;上边没有任何颜色&#xff0c;如下图&#xff0c;我们可以使用画笔工具在空白相处图层上进行修改&#xff1a; 智能图层 智能图层可以记录该图层当前的数据在被编辑后可…

条例26~30(实现)

条例26 尽可能延后变量定义式出现的时间 尽可能的延后定义一个变量&#xff0c;因为只要你定义出来哪怕你没有使用&#xff0c;也得承受构造和析构成本。假如有异常抛出的情况&#xff0c;你定义类一个变量还没有使用的时候就抛出了异常。这个变量就直接调用了析构&#xff0…

School‘s Java test

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;那个传说中的man的主页 &#x1f3e0;个人专栏&#xff1a;题目解析 &#x1f30e;推荐文章&#xff1a;题目大解析&#xff08;3&#xff09; 目录 &#x1f449;&#x1f3fb;第四周素数和念整数 &#…

MongoDB的作用和安装方法

MongoDB是一种非关系型数据库&#xff0c;其作用是存储和管理非结构化数据&#xff0c;例如文档、图像和视频等多媒体数据。它有以下几个特点&#xff1a; 数据存储的格式是类似JSON的文档格式&#xff0c;易于理解、存储和查询。可扩展性强&#xff0c;可以在多个服务器上分布…