Drogon 框架官方示例集解读:从 Hello World 到反向代理、WebSocket 与 Redis 实战 后端Web框架【免费下载链接】drogonDrogon: A C14/17/20 based HTTP web application framework running on Linux/macOS/Unix/Windows项目地址https://gitcode.com/gh_mirrors/dr/drogon点击查看免费下载导读本文以 Drogon 仓库中的 examples/README.md 为主线逐一剖析框架自带的 14 个官方示例从最基础的多种 Hello, World! 写法lambda 路由、HttpController、HttpSimpleController CSP 视图到 HTTP 客户端、WebSocket 聊天室、会话登录、文件上传、反向代理、RESTful 服务、Redis 集成、Prometheus 监控与 CORS 支持。通过阅读本文你将掌握 Drogon 框架各类核心能力的最小可运行代码形态知道每个示例对应仓库中的哪些文件、如何构建运行以及背后涉及的框架机制如 registerHandler 路由、Method 路由注册、PubSubService、协程 Redis 客户端、PreRouting/PostHandling 切片等可直接作为自己项目的起步模板。示例总览14 个官方示例一图览examples/README.md将示例分为 14 项覆盖 Drogon 的六大能力面能力面示例目录核心看点HTTP 服务端helloworld4 种路由写法 CSP 模板视图HTTP 客户端client_exampleHttpClient 异步请求、SockOpt 回调WebSocketwebsocket_server / websocket_client聊天室服务端 / 客户端连接与心跳会话login_session内置 Session 登录 / 登出文件上传file_uploadMultiPartParser 解析与保存反向代理simple_reverse_proxy插件实现的轮询反代性能基准benchmark基准测试控制器 JSON 响应RESTfuljsonstore内存并发 JSON 存储服务Redisredis、redis_chat、redis_cache键值读写、Pub/Sub 聊天室、协程缓存可观测性prometheus_examplePrometheus Exporter 指标采集跨域corsCORS 预检与响应头注入此外仓库中的 examples/CMakeLists.txt 还额外定义了 async_stream异步流式响应与请求流示例它虽未出现在 README 列表中但同样是官方可编译运行的例子本文一并解读。构建与运行示例所有示例统一由 examples/CMakeLists.txt 组织编译在主工程cmake配置完成后会自动生成。每个示例都是一个独立可执行程序add_executable(helloworld helloworld/main.cc helloworld/HelloController.cc helloworld/HelloViewController.cc) add_executable(jsonstore jsonstore/main.cc) add_executable(redis_simple redis/main.cc redis/controllers/Client.cc redis/controllers/WsClient.cc) add_executable(cors cors/main.cc)几个值得注意的构建细节源自 examples/CMakeLists.txt需要 CSP 视图的示例如helloworld、file_upload、login_session通过drogon_create_views()在编译期把.csp模板编译为 C 源码所有示例目标统一输出到${CMAKE_CURRENT_BINARY_DIR}/bin目录并可通过install(TARGETS ...)安装到${INSTALL_BIN_DIR}非 Windows GNU 编译器环境下示例会额外开启-Wall -Wextra -Werror严格警告保证示例代码质量示例统一使用DROGON_CXX_STANDARD并强制开启CXX_STANDARD_REQUIRED ON说明 Drogon 的示例面向 C14/17/20 编写。部分示例simple_reverse_proxy、redis_cache、prometheus_example采用loadConfigFile()读取config.json运行使用前需确保配置文件路径正确redis_cache的 README.md 还提示协程用法需要较新的编译器GCC 10 需-stdc20 -fcoroutinesGCC ≥ 11 与 MSVC ≥ 16.25 直接-stdc20//std:c20。HTTP 服务端helloworld 的四种路由写法helloworld 是理解 Drogon 路由体系的入门示例它在一个项目里同时演示了四种响应 Hello, World! 的方式源码分布在main.cc、HelloController.cc、HelloViewController.cc与 CSP 模板中。方式一registerHandler 路径参数examples/helloworld/main.cc 用app().registerHandler()注册 lambda 处理器。Drogon 支持在路径中用{}声明参数花括号内的文字仅供识别用途、不参与匹配索引/user/{user-name}会把捕获段作为第三个参数传给 handlerapp().registerHandler( /user/{user-name}, [](const HttpRequestPtr , std::functionvoid(const HttpResponsePtr ) callback, const std::string name) { auto resp HttpResponse::newHttpResponse(); resp-setBody(Hello, name !); callback(resp); }, {Get});方式二query 参数绑定Drogon 还允许把参数声明在 query 区/hello?user{user-name}会自动从 URL 查询串中取值并注入 handler 参数与路径参数使用体验完全一致。方式三手动解析请求参数main.cc 展示了不依赖框架解析、自行读取参数的做法通过req-getOptionalParameterstd::string(user)获得std::optional从而区分未传参与传了空值app().registerHandler( /hello_user, [](const HttpRequestPtr req, std::functionvoid(const HttpResponsePtr ) callback) { auto resp HttpResponse::newHttpResponse(); auto name req-getOptionalParameterstd::string(user); if (!name) resp-setBody(Please tell me your name); else resp-setBody(Hello, name.value() !); callback(resp); }, {Get});方式四HttpController 与 HttpSimpleControllerHelloController.cc 展示了传统面向对象写法继承HttpControllerSayHello用METHOD_LIST_BEGIN/METHOD_LIST_END宏批量注册方法。关键细节HttpController 会自动把命名空间 类名前缀拼到路径上因此METHOD_ADD(SayHello::genericHello, /, Get)最终落在/SayHello/注意结尾斜杠/SayHello与/SayHello/是两个不同路径。而 HelloViewController.cc 使用轻量的HttpSimpleController它只允许一个处理器asyncHandleHttpRequest且不会自动添加类名前缀PATH_ADD(/view)的路径就是/view。CSP 模板视图HelloViewController通过HttpResponse::newHttpViewResponse(HelloView, data)渲染 HelloView.csp。CSP 模板用%c ... %内嵌 C 逻辑、代表注入的HttpViewData、[[ name ]]做变量输出、$$指向输出流%c auto name.getstd::string(name); bool nameIsEmpty name ; if (nameIsEmpty) name anonymous; auto message Hello, name from a CSP template; %同时main.cc还演示了setBeforeListenSockOptCallback在 Linux 上给监听 socket 开启TCP_FASTOPEN与多监听端口addListener(127.0.0.1, 8848)如需再监听 5555 端口再加一行即可的用法。HTTP 客户端client_exampleclient_example/main.cc 演示了 Drogon 内置 HTTP 客户端的完整用法HttpClient::newHttpClient(http://www.baidu.com)创建客户端client-setSockOptCallback()在每个新连接建立时设置 socket 选项示例在 Linux 上配置TCP_KEEPCNT/TCP_KEEPIDLE/TCP_KEEPINTVL保活参数构造HttpRequest设置Get方法、路径/s与参数wdwx、oqwx循环sendRequest()发送 10 个异步请求回调中检查ReqResult::Ok、打印响应体、遍历响应 cookies含 domain 信息client-requestsBufferSize()查看待发送请求的缓冲队列大小。示例把日志级别设为trantor::Logger::kTrace见 main.cc便于观察网络层细节最后app().run()启动事件循环以驱动异步客户端完成收发。这个示例说明 Drogon 的 HttpClient 是事件循环驱动的非阻塞客户端适用于抓取上游数据、聚合网关等场景。WebSocket 双向实战websocket_server 与 websocket_client服务端基于 PubSubService 的聊天室websocket_server/WebSocketServer.cc 是一个完整可用的 WebSocket 聊天室继承WebSocketControllerWebSocketChat并实现三个回调handleNewConnection连接建立时先向客户端send(haha!!!)读取room_name参数调用chatRooms_.subscribe()订阅对应房间并把订阅信息setContext到连接上handleNewMessage对Text消息调用chatRooms_.publish()广播给房间内所有订阅者对Ping消息单独记录日志handleConnectionClosed通过getContextRefSubscriber()取出订阅信息并unsubscribe退订避免消息泄漏到已断开连接。其中chatRooms_是框架提供的进程内发布/订阅服务PubSubServicestd::string定义见 lib/inc/drogon/PubSubService.h它让聊天室广播逻辑变得极其简洁。路径注册同时支持精确路径与正则WS_PATH_ADD(/chat, Get)WS_ADD_PATH_VIA_REGEX(/[^/]*, Get)。客户端连接、消息类型与心跳websocket_client/WebSocketClient.cc 演示客户端用法支持-p参数切换为连接公共 echo 服务器wss://否则默认连接本地ws://127.0.0.1:8848/chatWebSocketClient::newWebSocketClient(serverString)创建客户端setMessageHandler按WebSocketMessageType区分 text/pong/ping/binary/Close 消息setConnectionClosedHandler处理断连connectToServer()回调成功后设置setPingMessage(, 2s)每 2 秒发送心跳并send(hello!)通过app().getLoop()-runAfter(15, []() { app().quit(); })在 15 秒后自动退出程序方便演示。会话系统login_sessionlogin_session/main.cc 演示了 Drogon 内置 Session 系统的登录 / 登出完整闭环启动时调用.enableSession(24h)所有会话有效期 24 小时GET /通过req-session()-getOptionalbool(loggedIn)判断登录态未登录渲染LoginPage视图已登录渲染LogoutPage视图POST /login校验用户名密码成功则req-session()-insert(loggedIn, true)并重定向回首页失败返回k401UnauthorizedPOST /logout执行req-session()-erase(loggedIn)清除登录标记。源码中还留有一句值得铭记的安全提示main.cc生产环境绝不要用 MD5 做密码哈希应使用 Argon2 或 BCrypt示例使用 MD5 仅仅是因为 Drogon 不是加密库、不内置更强的哈希算法。文件上传file_uploadfile_upload/file_upload.cc 演示 multipart 文件上传的完整链路GET /渲染 FileUpload.csp 页面该模板内置了一段带进度条progressBar、上传速度与剩余时间统计的XMLHttpRequest前端 JSPOST /upload_endpoint使用MultiPartParserfileUpload.parse(req)失败或文件数不为 1 时返回k403Forbidden成功则取首个文件计算 MD5file.getMd5()调用file.save()落盘并把 MD5 返回给客户端启动配置.setClientMaxBodySize(20 * 2000 * 2000)放大请求体上限.setUploadPath(./uploads)指定保存目录。这个示例对应框架的 lib/inc/drogon/MultiPart.h 与 lib/inc/drogon/UploadFile.h是文件上传业务的最小可参考实现。反向代理simple_reverse_proxysimple_reverse_proxy 展示如何用 Drogon 的插件机制实现一个带简单轮询round robin的 HTTP 反向代理项目由drogon_ctl脚手架生成见其 README.md。SimpleReverseProxy.cc 的核心逻辑initAndStart()从插件配置读取backends后端地址数组、pipeliningHTTP pipelining 深度、same_client_to_same_backend同一客户端是否固定同一后端、connection_factor每个事件循环中每个后端建立的连接数并用drogon::app().registerPreRoutingAdvice()注册前置切片preRouting()按轮询或按客户端 IP 哈希std::hashuint32_t{}(req-getPeerAddr().ipNetEndian())选择后端HttpClientPtr懒创建客户端并设置 pipelining 深度通过req-setPassThrough(true)把请求直接透传转发响应成功则resp-setPassThrough(true)后回调失败则构造k500InternalServerError。对应的 config.json 展示了插件注册方式——plugins数组中声明name: my_plugin::SimpleReverseProxy并给出config对象该文件同时是一份注释完整的 Drogon 配置字典threads_num、enable_session、document_root、file_types、log、client_max_body_size等字段均有默认值与含义说明适合作为 JSON 配置入门参考。性能基准benchmark 与官方基准测试套件benchmark 是一个极简压测目标main.cc用registerSyncAdvice直接对/返回pHello, world!/p同步切片短路响应并setThreadNum(0)让 IO 线程数等于 CPU 核数BenchmarkCtrl.cc 与 JsonCtrl.cc 分别提供纯文本与 JSON 两个响应形态setExpiredTime(0)关闭缓存保证每次都真实渲染。监听地址为0.0.0.0:7770日志级别为kWarn以减少压测噪声。README 还提到作者维护了两套第三方基准测试套件TechEmpower Framework Benchmarkstfb与the-benchmarker/web-frameworksDrogon 以本地子模块方式内嵌。这两套套件不在本仓库内如需复现可直接查看上述两个基准项目的 Drogon 目录在 README 中给出了对应位置。RESTful 服务jsonstorejsonstore/main.cc 实现了一个 jsonstore 风格的、并发安全的内存 JSON 存储服务被 README 评价为展示如何用 Drogon 构建最小可用 RESTful API的范例。其路由设计颇有参考价值方法路由说明GET/get-token用utils::secureRandomBytes生成 64 位十六进制 tokenGET/([a-f0-9]{64})/(.*)按路径读取 JSON 子树POST/([a-f0-9]{64})以 token 为键创建数据项PUT/([a-f0-9]{64})/(.*)更新路径下的 JSON 值DELETE/([a-f0-9]{64})删除数据项实现要点路由用ADD_METHOD_VIA_REGEX正则注册正则捕获组按顺序绑定到 handler 参数token、pathwalkJson()手工在Json::Value上按/分段下钻数组下标走isArray()分支用std::stoi转换实现a/b/0/c这类混合路径并发安全采用双层锁全局storageMtx_保护dataStore_增删每个DataItem自带mtx保护读写注释中明确说明读多写少场景下这可能阻塞同对象的其他读者但概率很低——这是对锁粒度权衡的坦诚示范响应用HttpResponse::newHttpJsonResponse统一产出 JSON。Redis 三连redis、redis_chat 与 redis_cacheredis键值读写 Pub/Sub 网关redis 的 README.md 给出了可直接执行的 curl 用例POST localhost:8080/client/foobody 带{value: bar}写入、GET localhost:8080/client/foo读取。Client.cc 用app().getRedisClient()-execCommandAsync()执行set %s %s/get %s命令成功回调中把 Redis 返回的 JSON 字符串二次解析后嵌入响应。WsClient.cc 进一步演示WebSocket 当 Redis 网关/sub连接用newSubscriber()订阅频道收到频道名即subscribe、unsub xxx即退订/pub连接把消息经PUBLISH命令广播并把订阅者数量回传给发送方。连接关闭时通过clearContext()释放订阅者析构时自动退订。redis_chatWebSocket Redis Pub/Sub 聊天室redis_chat 把聊天室做成了分布式形态房间广播依赖 Redis Pub/Sub 而非进程内PubSubService。Chat.cc 的要点登录互斥用Lua 脚本原子完成GET判存在不存在才SET key 1 EX timeout通过EVAL提交从根源上避免同一用户名重复登录的竞态心跳保活收到Pong消息即SET loginKey 1 EX 120续期 120 秒断线即DEL loginKey房间协议为文本指令ENTER roomNo房间号校验 0-99、QUIT、其余文本视为聊天消息经publish广播到房间频道subscriber_-subscribe()回调再把消息send回所有客户端源码注释明确警告把用户名直接拼进 Redis 命令存在注入风险生产环境严禁照抄Chat.cc。redis_cacheRedis 客户端协程与缓存模式redis_cache 展示 Redis 客户端的协程接口实现基于 Redis 的会话/缓存。RedisCache.h 定义了三个模板函数template typename T drogon::TaskT getFromCache(const std::string key, const drogon::nosql::RedisClientPtr client) { auto value co_await client-execCommandCoro(get %s, key.data()); co_return fromStringT(value.asString()); } template typename T drogon::Task updateCache(const std::string key, T value, const drogon::nosql::RedisClientPtr client) { std::string vstr toString(std::forwardT(value)); co_await client-execCommandCoro(set %s %s, key.data(), vstr.data()); }配套的 DateFuncs.h 提供trantor::Date的fromString/toString特化内部用微秒时间戳互转。业务层SlowCtrl.cc 的observe是AsyncTask协程控制器co_await getFromCachetrantor::Date()读取上次访问时间异常时返回 404TimeFilter.cc 在doFilter中通过drogon::async_run启动协程实现10 秒内禁止重复访问的频控逻辑命中缓存且now lastDate.after(10)时返回 JSON 错误并短路否则updateCache后放行控制器用ADD_METHOD_TO(SlowCtrl::hello, /slow?userid{userid}, Get, TimeFilter)把过滤器挂到路由上见 SlowCtrl.h。其 config.json 展示了redis_clients配置段is_fast: true时每个 IO 线程按number_of_connections建连接适合协程高频调用timeout: -1.0表示命令无超时该文件还包含locations静态资源映射、use_brotli/br_static等较新的配置项。可观测性prometheus_exampleprometheus_example 演示如何在 Drogon 中启用 Prometheus Exporter框架内置插件drogon::plugin::PromExporter源码见 lib/src/PromExporter.cc配套监控指标组件见 lib/inc/drogon/utils/monitoring。config.json 中插件声明了两个指标http_requests_totalcounter 类型标签method、pathhttp_request_duration_secondshistogram 类型标签同上指标暴露路径为/metrics。采集逻辑写在 PromStat.cc一个中间件/过滤器请求进入时取req-matchedPathPattern()与方法名对http_requests_total执行collector-metric({method, path})-increment()co_await next等待下游处理完成后用trantor::Date::date()计算耗时微秒以{0.0001, 0.001, 0.01, 0.1, 0.5, 1, 2, 3}为直方图边界observe()记录耗时秒数直方图同时指定了 1 小时窗口与 6 个 bucket 分组PromTestCtrl.cc 提供fast与slow协程sleepCoro随机睡 1-3 秒两个端点用于观察指标差异。该示例同时演示了通过app().getPlugindrogon::plugin::PromExporter()在运行时获取插件实例的依赖注入模式。跨域corscors/main.cc 演示纯代码实现 CORS 支持无需额外配置setupCors()注册两段切片registerSyncAdvice拦截OPTIONS预检请求把Origin、Access-Control-Request-Method、Access-Control-Request-Headers原样反射为Access-Control-Allow-*响应头并固定加Access-Control-Allow-Credentials: trueregisterPostHandlingAdvice则在所有响应生成后再次注入同样的 CORS 头保证普通 GET/POST 响应也能跨域读取路由侧registerHandler(/hello, ..., {Get, Options})把OPTIONS显式加入方法集合确保预检请求能命中 handler文件头注释给出了两条 curl 验证命令OPTIONS预检与带Origin头的POST /echoecho 接口原样回显请求体。这套同步切片处理预检 后置切片注入响应头的组合是理解 Drogon AOP 切片机制对应 lib/src/AOPAdvice.cc 中registerSyncAdvice/registerPostHandlingAdvice的实现的绝佳案例。附录README 未列出的 async_streamexamples/CMakeLists.txt 中还注册了 README 列表之外的 async_stream 示例演示 Drogon 的双向流式能力main.cc的/stream用HttpResponse::newAsyncStreamResponse()在独立线程里分两次send(hello )、send(world)后close()实现分块推送响应配合setContentTypeCodeAndCustomString指定 MIME/stream_req演示请求流app().enableRequestStream()开启后 handler 可收到RequestStreamPtr用RequestStreamReader::newReader按分片消费请求体RequestStreamExampleCtrl.cc 给出两个进阶场景/stream_echo把请求流逐片回显到响应流StreamEchoReader/stream_upload用newMultipartReader在流式收到 multipart 分片时即时写入uploads/临时文件实现边传边存的大文件上传。若你的场景涉及 SSE、流式推理回传或超大上传这份示例是最直接的参考。总结examples/README.md虽是一份简短索引但每个条目背后都是可直接编译运行的完整工程。把它们串联起来看恰好勾勒出 Drogon 框架的完整能力版图lambda 与面向对象双轨路由、CSP 模板视图、异步 HTTP 客户端、WebSocket 服务端/客户端、内置会话、文件上传、插件化扩展反向代理、Prometheus 指标、Redis 键值与 Pub/Sub、协程化 IO以及 AOP 切片机制预路由/后处理。建议按helloworld → login_session → file_upload → websocket_server → redis_cache → cors → simple_reverse_proxy → prometheus_example的顺序阅读源码可以平滑地从写一个路由进阶到搭建一个可观测、可扩展、可跨域的生产级服务。赞分享后端Web框架【免费下载链接】drogonDrogon: A C14/17/20 based HTTP web application framework running on Linux/macOS/Unix/Windows项目地址https://gitcode.com/gh_mirrors/dr/drogon点击查看免费下载相关推荐Hyper 官方示例代码全解析从 Hello World 到反向代理、优雅停机与 HTTP 升级Hyper 官方示例代码全解析从 Hello World 到反向代理、优雅停机与 HTTP 升级 本篇技术指南以 hyper 仓库 examples/READ后端网络dva 官方示例与社区脚手架全景解析从 Hello World 到中后台实战dva 官方示例与社区脚手架全景解析从 Hello World 到中后台实战 导读 本文以 examples and boilerplates.md http前端Nuclio 官方函数示例全景解读从 Hello World 到 TensorFlow 的七种运行时实战Nuclio 官方函数示例全景解读从 Hello World 到 TensorFlow 的七种运行时实战 Nuclio 是一个高性能的 Serverless云原生后端微服务上一篇三步智能捕获猫抓插件如何高效解决网页媒体资源下载难题下一篇YimMenu终极教程5步掌握GTA5最强免费防崩溃辅助工具创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考