• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

drogon: 基于C++14/17的跨平台高性能HTTP web应用框架

原作者: [db:作者] 来自: 网络 收藏 邀请

开源软件名称:

drogon
加入 Gitee
与超过 800 万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
trantor

开源软件地址:

https://gitee.com/an-tao/drogon

开源软件介绍:

Build StatusBuild StatusTotal alertsJoin the chat at https://gitter.im/drogon-web/communityJoin the telegram group at https://t.me/joinchat/_mMNGv0748ZkMDAxDocker image

English | 简体中文 | 繁體中文

Drogon是一个基于C++14/17的Http应用框架,使用Drogon可以方便的使用C++构建各种类型的Web应用服务端程序。本版本库是github上Drogon工程的镜像库。Drogon是作者非常喜欢的美剧《权力的游戏》中的一条龙的名字(汉译作卓耿),和龙有关但并不是dragon的误写,为了不至于引起不必要的误会这里说明一下。

Drogon是一个跨平台框架,它支持Linux,也支持macOS、FreeBSD,OpenBSD,HaikuOS,和Windows。它的主要特点如下:

  • 网络层使用基于epoll(macOS/FreeBSD下是kqueue)的非阻塞IO框架,提供高并发、高性能的网络IO。详细请见TFB Tests Results
  • 全异步编程模式;
  • 支持Http1.0/1.1(server端和client端);
  • 基于template实现了简单的反射机制,使主程序框架、控制器(controller)和视图(view)完全解耦;
  • 支持cookies和内建的session;
  • 支持后端渲染,把控制器生成的数据交给视图生成Html页面,视图由CSP模板文件描述,通过CSP标签把C++代码嵌入到Html页面,由drogon的命令行工具在编译阶段自动生成C++代码并编译;
  • 支持运行期的视图页面动态加载(动态编译和加载so文件);
  • 非常方便灵活的路径(path)到控制器处理函数(handler)的映射方案;
  • 支持过滤器(filter)链,方便在控制器之前执行统一的逻辑(如登录验证、Http Method约束验证等);
  • 支持https(基于OpenSSL实现);
  • 支持websocket(server端和client端);
  • 支持Json格式请求和应答, 对Restful API应用开发非常友好;
  • 支持文件下载和上传,支持sendfile系统调用;
  • 支持gzip/brotli压缩传输;
  • 支持pipelining;
  • 提供一个轻量的命令行工具drogon_ctl,帮助简化各种类的创建和视图代码的生成过程;
  • 基于非阻塞IO实现的异步数据库读写,目前支持PostgreSQL和MySQL(MariaDB)数据库;
  • 基于线程池实现sqlite3数据库的异步读写,提供与上文数据库相同的接口;
  • 支持Redis异步读写;
  • 支持ARM架构;
  • 方便的轻量级ORM实现,支持常规的对象到数据库的双向映射操作;
  • 支持插件,可通过配置文件在加载期动态拆装;
  • 支持内建插入点的AOP
  • 支持C++协程

一个非常简单的例子

不像大多数C++框架那样,drogon的主程序可以保持非常简单。 Drogon使用了一些小技巧使主程序和控制器解耦合. 控制器的路由设置可以在控制器类中定义或者配置文件中完成.

下面是一个典型的主程序的样子:

#include <drogon/drogon.h>using namespace drogon;int main(){    app().setLogPath("./")         .setLogLevel(trantor::Logger::kWarn)         .addListener("0.0.0.0", 80)         .setThreadNum(16)         .enableRunAsDaemon()         .run();}

如果使用配置文件,可以进一步简化成如下的样子:

#include <drogon/drogon.h>using namespace drogon;int main(){    app().loadConfigFile("./config.json").run();}

当然,Drogon也提供了一些接口,使用户可以在main()函数中直接添加控制器逻辑,比如,用户可以注册一个lambda处理器到drogon框架中,如下所示:

app().registerHandler("/test?username={name}",                    [](const HttpRequestPtr& req,                       std::function<void (const HttpResponsePtr &)> &&callback,                       const std::string &name)                    {                        Json::Value json;                        json["result"]="ok";                        json["message"]=std::string("hello,")+name;                        auto resp=HttpResponse::newHttpJsonResponse(json);                        callback(resp);                    },                    {Get,"LoginFilter"});

这看起来是很方便,但是这并不适用于复杂的应用,试想假如有数十个或者数百个处理函数要注册进框架,main()函数将膨胀到不可读的程度。显然,让每个包含处理函数的类在自己的定义中完成注册是更好的选择。所以,除非你的应用逻辑非常简单,我们不推荐使用上述接口,更好的实践是,我们可以创建一个HttpSimpleController对象,如下:

/// The TestCtrl.h file#pragma once#include <drogon/HttpSimpleController.h>using namespace drogon;class TestCtrl:public drogon::HttpSimpleController<TestCtrl>{public:    virtual void asyncHandleHttpRequest(const HttpRequestPtr& req, std::function<void (const HttpResponsePtr &)> &&callback) override;    PATH_LIST_BEGIN    PATH_ADD("/test",Get);    PATH_LIST_END};/// The TestCtrl.cc file#include "TestCtrl.h"void TestCtrl::asyncHandleHttpRequest(const HttpRequestPtr& req,                                      std::function<void (const HttpResponsePtr &)> &&callback){    //write your application logic here    auto resp = HttpResponse::newHttpResponse();    resp->setBody("<p>Hello, world!</p>");    resp->setExpiredTime(0);    callback(resp);}

上面程序的大部分代码都可以由drogon_ctl命令创建(这个命令是drogon_ctl create controller TestCtr)。用户所需做的就是添加自己的业务逻辑。在这个例子中,当客户端访问URLhttp://ip/test时,控制器简单的返回了一个Hello, world!页面。

对于JSON格式的响应,我们可以像下面这样创建控制器:

/// The header file#pragma once#include <drogon/HttpSimpleController.h>using namespace drogon;class JsonCtrl : public drogon::HttpSimpleController<JsonCtrl>{  public:    virtual void asyncHandleHttpRequest(const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback) override;    PATH_LIST_BEGIN    //list path definitions here;    PATH_ADD("/json", Get);    PATH_LIST_END};/// The source file#include "JsonCtrl.h"void JsonCtrl::asyncHandleHttpRequest(const HttpRequestPtr &req,                                      std::function<void(const HttpResponsePtr &)> &&callback){    Json::Value ret;    ret["message"] = "Hello, World!";    auto resp = HttpResponse::newHttpJsonResponse(ret);    callback(resp);}

让我们更进一步,通过HttpController类创建一个RESTful API的例子,如下所示(忽略了实现文件):

/// The header file#pragma once#include <drogon/HttpController.h>using namespace drogon;namespace api{namespace v1{class User : public drogon::HttpController<User>{  public:    METHOD_LIST_BEGIN    //use METHOD_ADD to add your custom processing function here;    METHOD_ADD(User::getInfo, "/{id}", Get);                  //path is /api/v1/User/{arg1}    METHOD_ADD(User::getDetailInfo, "/{id}/detailinfo", Get);  //path is /api/v1/User/{arg1}/detailinfo    METHOD_ADD(User::newUser, "/{name}", Post);                 //path is /api/v1/User/{arg1}    METHOD_LIST_END    //your declaration of processing function maybe like this:    void getInfo(const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback, int userId) const;    void getDetailInfo(const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback, int userId) const;    void newUser(const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback, std::string &&userName);  public:    User()    {        LOG_DEBUG << "User constructor!";    }};} // namespace v1} // namespace api

如你所见,通过HttpController类,用户可以同时映射路径和路径参数,这对RESTful API应用来说非常方便。

另外,你可以发现前面所有的处理函数接口都是异步的,处理器的响应是通过回调对象返回的。这种设计是出于对高性能的考虑,因为在异步模式下,可以使用少量的线程(比如和处理器核心数相等的线程)处理大量的并发请求。

编译上述的所有源文件后,我们得到了一个非常简单的web应用程序,这是一个不错的开始。请访问wiki或者doxiz以获取更多的信息

贡献方式

欢迎您的贡献。 请阅读贡献指南以获取更多的信息。

QQ交流群:1137909452

欢迎交流探讨。


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap