项目简单(仅为学习)
我并不是很会这个框架 还在学习中
环境准备(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)