14 changed files with 458 additions and 0 deletions
@ -0,0 +1,22 @@ |
|||||||
|
{ |
||||||
|
"configurations": [ |
||||||
|
{ |
||||||
|
"name": "Win32", |
||||||
|
"includePath": [ |
||||||
|
"${workspaceFolder}/**", |
||||||
|
"${vcpkgRoot}/x64-mingw-static/include/**" |
||||||
|
], |
||||||
|
"defines": [ |
||||||
|
"_DEBUG", |
||||||
|
"UNICODE", |
||||||
|
"_UNICODE" |
||||||
|
], |
||||||
|
"compilerPath": "C:/ProgramData/chocolatey/lib/mingw/tools/install/mingw64/bin/g++.exe", |
||||||
|
"cStandard": "c17", |
||||||
|
"cppStandard": "c++17", |
||||||
|
"intelliSenseMode": "windows-gcc-x64", |
||||||
|
"configurationProvider": "ms-vscode.cmake-tools" |
||||||
|
} |
||||||
|
], |
||||||
|
"version": 4 |
||||||
|
} |
@ -0,0 +1,26 @@ |
|||||||
|
{ |
||||||
|
"version": "0.2.0", |
||||||
|
"configurations": [ |
||||||
|
{ |
||||||
|
"name": "g++.exe - Build and debug active file", |
||||||
|
"type": "cppdbg", |
||||||
|
"request": "launch", |
||||||
|
"program": "${workspaceFolder}/build/CppServerProject.exe", |
||||||
|
"args": [], |
||||||
|
"stopAtEntry": false, |
||||||
|
"cwd": "${workspaceFolder}", |
||||||
|
"environment": [], |
||||||
|
"externalConsole": false, |
||||||
|
"MIMode": "gdb", |
||||||
|
"miDebuggerPath": "C:/ProgramData/chocolatey/lib/mingw/tools/install/mingw64/bin/gdb.exe", |
||||||
|
"setupCommands": [ |
||||||
|
{ |
||||||
|
"description": "Enable pretty-printing for gdb", |
||||||
|
"text": "-enable-pretty-printing", |
||||||
|
"ignoreFailures": true |
||||||
|
} |
||||||
|
], |
||||||
|
"preLaunchTask": "C/C++: g++.exe build active file" |
||||||
|
} |
||||||
|
] |
||||||
|
} |
@ -0,0 +1,76 @@ |
|||||||
|
{ |
||||||
|
"files.associations": { |
||||||
|
"*.dbclient-js": "javascript", |
||||||
|
"any": "cpp", |
||||||
|
"array": "cpp", |
||||||
|
"atomic": "cpp", |
||||||
|
"strstream": "cpp", |
||||||
|
"bit": "cpp", |
||||||
|
"bitset": "cpp", |
||||||
|
"cctype": "cpp", |
||||||
|
"chrono": "cpp", |
||||||
|
"clocale": "cpp", |
||||||
|
"cmath": "cpp", |
||||||
|
"codecvt": "cpp", |
||||||
|
"compare": "cpp", |
||||||
|
"concepts": "cpp", |
||||||
|
"condition_variable": "cpp", |
||||||
|
"coroutine": "cpp", |
||||||
|
"csignal": "cpp", |
||||||
|
"cstdarg": "cpp", |
||||||
|
"cstddef": "cpp", |
||||||
|
"cstdint": "cpp", |
||||||
|
"cstdio": "cpp", |
||||||
|
"cstdlib": "cpp", |
||||||
|
"cstring": "cpp", |
||||||
|
"ctime": "cpp", |
||||||
|
"cwchar": "cpp", |
||||||
|
"cwctype": "cpp", |
||||||
|
"deque": "cpp", |
||||||
|
"list": "cpp", |
||||||
|
"map": "cpp", |
||||||
|
"set": "cpp", |
||||||
|
"string": "cpp", |
||||||
|
"unordered_map": "cpp", |
||||||
|
"unordered_set": "cpp", |
||||||
|
"vector": "cpp", |
||||||
|
"exception": "cpp", |
||||||
|
"algorithm": "cpp", |
||||||
|
"functional": "cpp", |
||||||
|
"iterator": "cpp", |
||||||
|
"memory": "cpp", |
||||||
|
"memory_resource": "cpp", |
||||||
|
"numeric": "cpp", |
||||||
|
"optional": "cpp", |
||||||
|
"random": "cpp", |
||||||
|
"ratio": "cpp", |
||||||
|
"regex": "cpp", |
||||||
|
"string_view": "cpp", |
||||||
|
"system_error": "cpp", |
||||||
|
"tuple": "cpp", |
||||||
|
"type_traits": "cpp", |
||||||
|
"utility": "cpp", |
||||||
|
"fstream": "cpp", |
||||||
|
"future": "cpp", |
||||||
|
"initializer_list": "cpp", |
||||||
|
"iomanip": "cpp", |
||||||
|
"iosfwd": "cpp", |
||||||
|
"iostream": "cpp", |
||||||
|
"istream": "cpp", |
||||||
|
"limits": "cpp", |
||||||
|
"mutex": "cpp", |
||||||
|
"new": "cpp", |
||||||
|
"numbers": "cpp", |
||||||
|
"ostream": "cpp", |
||||||
|
"semaphore": "cpp", |
||||||
|
"shared_mutex": "cpp", |
||||||
|
"sstream": "cpp", |
||||||
|
"stdexcept": "cpp", |
||||||
|
"stop_token": "cpp", |
||||||
|
"streambuf": "cpp", |
||||||
|
"thread": "cpp", |
||||||
|
"cinttypes": "cpp", |
||||||
|
"typeinfo": "cpp", |
||||||
|
"variant": "cpp" |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,33 @@ |
|||||||
|
{ |
||||||
|
"version": "2.0.0", |
||||||
|
"tasks": [ |
||||||
|
{ |
||||||
|
"type": "cppbuild", |
||||||
|
"label": "C/C++: g++.exe build active file", |
||||||
|
"command": "C:/ProgramData/chocolatey/lib/mingw/tools/install/mingw64/bin/g++.exe", |
||||||
|
"args": [ |
||||||
|
"-fdiagnostics-color=always", |
||||||
|
"-g", |
||||||
|
"${workspaceFolder}/*.cpp", |
||||||
|
"-o", |
||||||
|
"${workspaceFolder}/build/${fileBasenameNoExtension}.exe", |
||||||
|
"-I${vcpkgRoot}/x64-mingw-static/include", |
||||||
|
"-L${vcpkgRoot}/x64-mingw-static/lib", |
||||||
|
"-ldrogon", |
||||||
|
"-ljsoncpp", |
||||||
|
"-lrcpp" |
||||||
|
], |
||||||
|
"options": { |
||||||
|
"cwd": "${workspaceFolder}" |
||||||
|
}, |
||||||
|
"problemMatcher": [ |
||||||
|
"$gcc" |
||||||
|
], |
||||||
|
"group": { |
||||||
|
"kind": "build", |
||||||
|
"isDefault": true |
||||||
|
}, |
||||||
|
"detail": "Task generated by Debugger." |
||||||
|
} |
||||||
|
] |
||||||
|
} |
@ -0,0 +1,68 @@ |
|||||||
|
cmake_minimum_required(VERSION 3.12) |
||||||
|
project(CppServerProject) |
||||||
|
|
||||||
|
# 设置vcpkg工具链路径 |
||||||
|
set(CMAKE_TOOLCHAIN_FILE "D:/aigc/vcpkg/scripts/buildsystems/vcpkg.cmake" CACHE STRING "Vcpkg toolchain file") |
||||||
|
|
||||||
|
# 设置C++标准 |
||||||
|
set(CMAKE_CXX_STANDARD 17) |
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON) |
||||||
|
|
||||||
|
# 设置源文件目录 |
||||||
|
set(SOURCE_DIR src) |
||||||
|
|
||||||
|
# 查找依赖包 |
||||||
|
find_package(Drogon CONFIG REQUIRED) |
||||||
|
find_package(RapidJSON CONFIG REQUIRED) |
||||||
|
|
||||||
|
# 添加可执行文件 |
||||||
|
add_executable(${PROJECT_NAME} |
||||||
|
${SOURCE_DIR}/main.cpp |
||||||
|
${SOURCE_DIR}/controllers/HelloWorldController.cpp |
||||||
|
${SOURCE_DIR}/controllers/ApiController.cpp |
||||||
|
${SOURCE_DIR}/filters/ApiFilter.cpp |
||||||
|
) |
||||||
|
|
||||||
|
# 链接库 |
||||||
|
target_link_libraries(${PROJECT_NAME} PRIVATE |
||||||
|
Drogon::Drogon |
||||||
|
${CMAKE_DL_LIBS} # 用于动态加载 |
||||||
|
) |
||||||
|
|
||||||
|
# 包含目录 |
||||||
|
target_include_directories(${PROJECT_NAME} PRIVATE |
||||||
|
${SOURCE_DIR} |
||||||
|
${SOURCE_DIR}/controllers |
||||||
|
${SOURCE_DIR}/filters |
||||||
|
) |
||||||
|
|
||||||
|
# 配置文件拷贝 |
||||||
|
set(CONFIG_SRC "${CMAKE_CURRENT_SOURCE_DIR}/src/config/config.json") |
||||||
|
set(CONFIG_DEST "${CMAKE_CURRENT_BINARY_DIR}/Debug/config.json") |
||||||
|
|
||||||
|
add_custom_command( |
||||||
|
TARGET ${PROJECT_NAME} POST_BUILD |
||||||
|
COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CURRENT_BINARY_DIR}/Debug" |
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy |
||||||
|
"${CONFIG_SRC}" |
||||||
|
"${CONFIG_DEST}" |
||||||
|
COMMENT "Copying config.json to output directory" |
||||||
|
VERBATIM |
||||||
|
) |
||||||
|
|
||||||
|
# 处理多配置情况 |
||||||
|
if(CMAKE_CONFIGURATION_TYPES) |
||||||
|
foreach(CFG_TYPE ${CMAKE_CONFIGURATION_TYPES}) |
||||||
|
set(CFG_DIR "${CMAKE_CURRENT_BINARY_DIR}/${CFG_TYPE}") |
||||||
|
add_custom_command( |
||||||
|
TARGET ${PROJECT_NAME} POST_BUILD |
||||||
|
COMMAND ${CMAKE_COMMAND} -E make_directory "${CFG_DIR}" |
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy |
||||||
|
"${CONFIG_SRC}" |
||||||
|
"${CFG_DIR}/config.json" |
||||||
|
COMMENT "Copying config.json to ${CFG_TYPE} directory" |
||||||
|
VERBATIM |
||||||
|
) |
||||||
|
endforeach() |
||||||
|
endif() |
||||||
|
|
@ -0,0 +1,3 @@ |
|||||||
|
rm -Path build -Recurse -Force |
||||||
|
cmake -B build -DCMAKE_TOOLCHAIN_FILE="D:/aigc/vcpkg/scripts/buildsystems/vcpkg.cmake" |
||||||
|
cmake --build build |
@ -0,0 +1,25 @@ |
|||||||
|
{ |
||||||
|
"controllers": [ |
||||||
|
{ |
||||||
|
"name": "HelloWorldController", |
||||||
|
"path": "/" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"name": "ApiController", |
||||||
|
"path": "/" |
||||||
|
} |
||||||
|
], |
||||||
|
"filters": [ |
||||||
|
{ |
||||||
|
"name": "ApiFilter", |
||||||
|
"path": "/api/*" |
||||||
|
} |
||||||
|
], |
||||||
|
"listeners": [ |
||||||
|
{ |
||||||
|
"address": "0.0.0.0", |
||||||
|
"port": 8080, |
||||||
|
"ssl": false |
||||||
|
} |
||||||
|
] |
||||||
|
} |
@ -0,0 +1,48 @@ |
|||||||
|
#pragma once |
||||||
|
#include <drogon/HttpController.h> |
||||||
|
#include <drogon/HttpResponse.h> |
||||||
|
#include <json/json.h> |
||||||
|
|
||||||
|
using namespace drogon; |
||||||
|
|
||||||
|
class ApiController : public HttpController<ApiController> |
||||||
|
{ |
||||||
|
public: |
||||||
|
METHOD_LIST_BEGIN |
||||||
|
ADD_METHOD_TO(ApiController::getInfo, "/api/info", Get); |
||||||
|
ADD_METHOD_TO(ApiController::postData, "/api/data", Post); |
||||||
|
METHOD_LIST_END |
||||||
|
|
||||||
|
void getInfo(const HttpRequestPtr &req, |
||||||
|
std::function<void(const HttpResponsePtr &)> &&callback) |
||||||
|
{ |
||||||
|
Json::Value ret; |
||||||
|
ret["status"] = "ok"; |
||||||
|
ret["version"] = "1.0.0"; |
||||||
|
ret["message"] = "Welcome to CppServerProject"; |
||||||
|
|
||||||
|
auto resp = HttpResponse::newHttpJsonResponse(ret); |
||||||
|
callback(resp); |
||||||
|
} |
||||||
|
|
||||||
|
void postData(const HttpRequestPtr &req, |
||||||
|
std::function<void(const HttpResponsePtr &)> &&callback) |
||||||
|
{ |
||||||
|
auto json = req->getJsonObject(); |
||||||
|
if (!json) |
||||||
|
{ |
||||||
|
auto resp = HttpResponse::newHttpResponse(); |
||||||
|
resp->setStatusCode(k400BadRequest); |
||||||
|
resp->setBody("Invalid JSON data"); |
||||||
|
callback(resp); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
Json::Value ret; |
||||||
|
ret["status"] = "received"; |
||||||
|
ret["data"] = *json; |
||||||
|
|
||||||
|
auto resp = HttpResponse::newHttpJsonResponse(ret); |
||||||
|
callback(resp); |
||||||
|
} |
||||||
|
}; |
@ -0,0 +1,12 @@ |
|||||||
|
#include "HelloWorldController.h" |
||||||
|
|
||||||
|
using namespace drogon; |
||||||
|
|
||||||
|
void HelloWorldController::asyncHandleHttpRequest( |
||||||
|
const HttpRequestPtr &req, |
||||||
|
std::function<void(const HttpResponsePtr &)> &&callback) |
||||||
|
{ |
||||||
|
auto resp = HttpResponse::newHttpResponse(); |
||||||
|
resp->setBody("Hello, World!"); |
||||||
|
callback(resp); |
||||||
|
} |
@ -0,0 +1,15 @@ |
|||||||
|
#pragma once |
||||||
|
#include <drogon/HttpSimpleController.h> |
||||||
|
|
||||||
|
using namespace drogon; |
||||||
|
|
||||||
|
class HelloWorldController : public HttpSimpleController<HelloWorldController> |
||||||
|
{ |
||||||
|
public: |
||||||
|
PATH_LIST_BEGIN |
||||||
|
PATH_ADD("/hello", Get); |
||||||
|
PATH_LIST_END |
||||||
|
|
||||||
|
void asyncHandleHttpRequest(const HttpRequestPtr &req, |
||||||
|
std::function<void(const HttpResponsePtr &)> &&callback) override; |
||||||
|
}; |
@ -0,0 +1,24 @@ |
|||||||
|
#include "ApiFilter.h" |
||||||
|
|
||||||
|
using namespace drogon; |
||||||
|
|
||||||
|
ApiFilter::ApiFilter() {} |
||||||
|
|
||||||
|
void ApiFilter::doFilter(const HttpRequestPtr &req, |
||||||
|
FilterCallback &&fcb, |
||||||
|
FilterChainCallback &&fccb) |
||||||
|
{ |
||||||
|
// 简单的API密钥验证
|
||||||
|
auto apiKey = req->getHeader("X-API-KEY"); |
||||||
|
if (apiKey.empty() || apiKey != "secret-key") |
||||||
|
{ |
||||||
|
auto resp = HttpResponse::newHttpResponse(); |
||||||
|
resp->setStatusCode(k401Unauthorized); |
||||||
|
resp->setBody("Unauthorized: Invalid API Key"); |
||||||
|
fcb(resp); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
// 通过验证,继续处理
|
||||||
|
fccb(); |
||||||
|
}; |
@ -0,0 +1,14 @@ |
|||||||
|
|
||||||
|
#include <drogon/HttpFilter.h> |
||||||
|
|
||||||
|
using namespace drogon; |
||||||
|
|
||||||
|
class ApiFilter : public HttpFilter<ApiFilter> |
||||||
|
{ |
||||||
|
public: |
||||||
|
ApiFilter(); |
||||||
|
|
||||||
|
virtual void doFilter(const HttpRequestPtr &req, |
||||||
|
FilterCallback &&fcb, |
||||||
|
FilterChainCallback &&fccb) override; |
||||||
|
}; |
@ -0,0 +1,27 @@ |
|||||||
|
#include <drogon/drogon.h> |
||||||
|
#include <iostream> |
||||||
|
|
||||||
|
using namespace drogon; |
||||||
|
|
||||||
|
int main() |
||||||
|
{ |
||||||
|
try |
||||||
|
{ |
||||||
|
// 设置日志级别
|
||||||
|
drogon::app().setLogLevel(trantor::Logger::kTrace); |
||||||
|
drogon::app().registerBeginningAdvice([]() |
||||||
|
{ LOG_INFO << "Drogon application starting..."; }); |
||||||
|
|
||||||
|
// 加载配置
|
||||||
|
drogon::app().loadConfigFile("./config.json"); |
||||||
|
|
||||||
|
// 启动服务
|
||||||
|
drogon::app().run(); |
||||||
|
} |
||||||
|
catch (const std::exception &e) |
||||||
|
{ |
||||||
|
std::cerr << "Error: " << e.what() << std::endl; |
||||||
|
return 1; |
||||||
|
} |
||||||
|
return 0; |
||||||
|
} |
@ -0,0 +1,65 @@ |
|||||||
|
{ |
||||||
|
"openapi": "3.0.0", |
||||||
|
"info": { |
||||||
|
"title": "CppServerProject API", |
||||||
|
"version": "1.0.0", |
||||||
|
"description": "A sample C++ backend server with Swagger documentation" |
||||||
|
}, |
||||||
|
"paths": { |
||||||
|
"/hello": { |
||||||
|
"get": { |
||||||
|
"summary": "Hello World", |
||||||
|
"description": "Returns a simple greeting", |
||||||
|
"responses": { |
||||||
|
"200": { |
||||||
|
"description": "Successful response", |
||||||
|
"content": { |
||||||
|
"text/plain": { |
||||||
|
"schema": { |
||||||
|
"type": "string", |
||||||
|
"example": "Hello, World!" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
"/api/info": { |
||||||
|
"get": { |
||||||
|
"summary": "Get API info", |
||||||
|
"description": "Returns basic API information", |
||||||
|
"responses": { |
||||||
|
"200": { |
||||||
|
"description": "Successful response", |
||||||
|
"content": { |
||||||
|
"application/json": { |
||||||
|
"schema": { |
||||||
|
"$ref": "#/components/schemas/ApiInfo" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
"components": { |
||||||
|
"schemas": { |
||||||
|
"ApiInfo": { |
||||||
|
"type": "object", |
||||||
|
"properties": { |
||||||
|
"status": { |
||||||
|
"type": "string" |
||||||
|
}, |
||||||
|
"version": { |
||||||
|
"type": "string" |
||||||
|
}, |
||||||
|
"message": { |
||||||
|
"type": "string" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue