跳转至内容
  • 版块
  • 最新
  • 标签
  • 热门
  • Online Tools
  • 用户
  • 群组
折叠
品牌标识

D2Learn Forums

  1. 主页
  2. SubForums
  3. 现代C++ | mcpp论坛
  4. 在linux环境下创建C++ drogon 项目 进行接口测试(项目推动型学习)

在linux环境下创建C++ drogon 项目 进行接口测试(项目推动型学习)

已定时 已固定 已锁定 已移动 现代C++ | mcpp论坛
c++17web 高性能
1 帖子 1 发布者 14 浏览
  • 从旧到新
  • 从新到旧
  • 最多赞同
登录后回复
此主题已被删除。只有拥有主题管理权限的用户可以查看。
  • abbkiritoA 离线
    abbkiritoA 离线
    abbkirito
    编写于 最后由 编辑
    #1

    ​

    项目简单(仅为学习)
    我并不是很会这个框架 还在学习中
    环境准备(Ubuntu 22.04)

    gcc --version
    

    检查当前GCC版本:
    gcc --version
    e89ff7bd-b51b-4307-a36d-1633946d9aed-image.png
    ​​

    图1-1(C++版本查询)

    g++ -v --help 2>&1 | grep "std="
    

    若版本低于9.0,需执行以下升级操作:

    sudo apt update && sudo apt upgrade -y
    sudo apt install build-essential git cmake -y
    sudo apt install gcc-10 g++-10 -y
    

    验证C++17支持:

    g++ -v --help 2>&1 | grep "std="
    

    输出应包含gnu++17或c++17 例如:
    44588389-29ae-4f9f-b77a-a2b05a787e30-image.png

    3a1a02a9-8c7a-4c3f-a283-df44d21f8e0e-image.png

    MySQL依赖安装()

    安装MariaDB开发库drogon:

    sudo apt install -y libmariadb-dev
    

    创建源码目录并克隆仓库:

    mkdir drogon_src && cd drogon_src
    git clone https://github.com/drogonframework/drogon
    

    编译安装:

    cd drogon
    mkdir build && cd build
    cmake ..
    

    初次编译可能会遇到缺失trantor 子模块(Drogon 的网络库依赖)没有被正确下载或初始化。
    118d02d3-c6b4-48bf-b7aa-23320874463a-image.png

    笔者解决办法为:

    # 进入 Drogon 源码根目录
    cd ~/drogon/drogon
    
    # 初始化并更新所有子模块
    git submodule update --init --recursive
    

    编译

    编译安装 (nproc)调用当前可用核心数用于编译

    make -j$(nproc)
    

    等待编译:
    3e65e501-04c1-4834-a887-5dceac785151-image.png
    环境验证
    验证drogon 是否安装成功 出现以下版本信息即可。
    dd1d52ba-a9af-4ac2-a3e2-3e7050a5d9fa-image.png

    *** 使用drogon_ctl创建项目。**
             
            在自己喜欢的文件夹中创建项目

    6369b916-ea68-47b6-8df7-b4b0ae4a5af7-image.png

    drogon_ctl create project Hello-drogon
    cd Hello-drogon
    

    进入Hello-drogon的controllers 中在终端新建一个控制器。

    #drogon_ctl create controller [参数] [控制器名(自定义)] 
    drogon_ctl create controller -h drogonpic
    

    561bc505-8380-471c-b7cb-411941a64b8e-image.png
    编写测试接口
    23d96a12-94d0-4475-8af6-12fde87bad74-image.png
    编写一个简单的接口,该接口包含两个方法 路径为“api/pic”,“api/hello”,仅仅返回"hello drogon"的字符
    drogonpic.h 代码:

    // drogonpic.h 头文件编写。

    #pragma once
    
    #include <drogon/HttpController.h>
    
    using namespace drogon;
    
    class drogonpic : public drogon::HttpController<drogonpic>
    {
    public:
        METHOD_LIST_BEGIN
            // 确保类名正确
            ADD_METHOD_TO(drogonpic::getPic, "/api/pic", Get);
            ADD_METHOD_TO(drogonpic::hello, "/api/hello", Get);
        METHOD_LIST_END
        //hello world 
         void hello(const HttpRequestPtr& req,
                    std::function<void(const HttpResponsePtr&)>&& callback) const;
    
        // 图片获取方法
        void getPic(const HttpRequestPtr& req,
                    std::function<void(const HttpResponsePtr&)>&& callback) const;
        
    };
    

    实现drogonpic.cc

    #include "drogonpic.h"
    #include <drogon/HttpResponse.h>
    #include <drogon/drogon.h> // 添加日志支持
    #include <sys/stat.h>
    
    using namespace drogon;
    
    void drogonpic::getPic(const HttpRequestPtr& req,
                           std::function<void(const HttpResponsePtr&)>&& callback) const
    {
        // 使用绝对路径更可靠
        const std::string imagePath = "/home/xhm/xhm/Drogon-Project/Hello-drogon/assets/pic2.png";
        
        // 记录路径信息(调试用)
        LOG_INFO << "Attempting to load image: " << imagePath;
        
        // 检查文件是否存在
        struct stat buffer;
        if (stat(imagePath.c_str(), &buffer) != 0) 
        {
            LOG_ERROR << "Image not found: " << imagePath;
            auto resp = HttpResponse::newHttpResponse();
            resp->setStatusCode(k404NotFound);
            resp->setBody("Image not found");
            callback(resp);
            return;
        }
    
        // 创建文件响应
        auto resp = HttpResponse::newFileResponse(imagePath, "", CT_IMAGE_PNG);
        
        if (!resp) 
        {
            LOG_ERROR << "Failed to open image: " << imagePath;
            resp = HttpResponse::newHttpResponse();
            resp->setStatusCode(k500InternalServerError);
            resp->setBody("Failed to open image");
        }
        else 
        {
            LOG_INFO << "Image loaded successfully: " << imagePath;
        }
        
        callback(resp);
    }
    
    
    
            // 处理GET请求的方法
            void drogonpic::hello(const HttpRequestPtr& req,
                std::function<void(const HttpResponsePtr&)>&& callback) const
        {
            // 创建HTTP响应对象
            auto resp = HttpResponse::newHttpResponse();
    
            // 设置响应内容
            resp->setBody("hello world");
    
            // 设置响应状态码(可选,默认200)
            // resp->setStatusCode(k200OK);
    
            // 通过回调返回响应
            callback(resp);
        }
    

    对接口进行测试
    对api/hello 测试 使用apipost 进行测试 测试结果如下图所示:ip地址为linux主机的ip

    网页访问:
    04bb82cd-049f-4665-9037-9c5c44598877-image.png
    a8f35a9d-29d1-4a3c-ae98-4c4a87e71c1d-image.png

    压测结果:

    对api/pic 测试 给接口是返回一张图片
    dd3fe72b-3b64-4e04-8786-84498286286f-image.png

    网页访问:
    8ebacd02-fef5-4cfa-bbc5-61f575de4198-image.png
    压测结果:

    149852d2-c08d-466d-9d7e-c00547fa34ce-image.png
    总结

    : C++特性 代码示例
    #pragma once #pragma once
    CRTP模板继承 class X : public drogon::HttpController<X>
    auto 自动推导 auto resp = HttpResponse::newHttpResponse();
    右值引用 && std::function<void(const T&)>&& callback
    std::function std::function<void(const HttpResponsePtr&)>
    智能指针 HttpRequestPtr, HttpResponsePtr
    const 成员函数 void getPic(...) const
    C++调用C接口 stat(path.c_str(), &buffer)

    ​

    1 条回复 最后回复
    1

    • 登录

    • 没有帐号? 注册

    • 登录或注册以进行搜索。
    d2learn forums Powered by NodeBB
    • 第一个帖子
      最后一个帖子
    0
    • 版块
    • 最新
    • 标签
    • 热门
    • Online Tools
    • 用户
    • 群组