开源软件名称(OpenSource Name):drogonframework/drogon开源软件地址(OpenSource Url):https://github.com/drogonframework/drogon开源编程语言(OpenSource Language):C++ 94.9%开源软件介绍(OpenSource Introduction):OverviewDrogon is a C++14/17-based HTTP application framework. Drogon can be used to easily build various types of web application server programs using C++. Drogon is the name of a dragon in the American TV series "Game of Thrones" that I really like. Drogon is a cross-platform framework, It supports Linux, macOS, FreeBSD, OpenBSD, HaikuOS, and Windows. Its main features are as follows:
A very simple exampleUnlike most C++ frameworks, the main program of the drogon application can be kept clean and simple. Drogon uses a few tricks to decouple controllers from the main program. The routing settings of controllers can be done through macros or configuration file. Below is the main program of a typical drogon application: #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();
} It can be further simplified by using configuration file as follows: #include <drogon/drogon.h>
using namespace drogon;
int main()
{
app().loadConfigFile("./config.json").run();
} Drogon provides some interfaces for adding controller logic directly in the main() function, for example, user can register a handler like this in 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"}); While such interfaces look intuitive, they are not suitable for complex business logic scenarios. Assuming there are tens or even hundreds of handlers that need to be registered in the framework, isn't it a better practice to implement them separately in their respective classes? So unless your logic is very simple, we don't recommend using above interfaces. Instead, we can create an HttpSimpleController as follows: /// The TestCtrl.h file
#pragma once
#include <drogon/HttpSimpleController.h>
using namespace drogon;
class TestCtrl:public drogon::HttpSimpleController<TestCtrl>
{
public:
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);
} Most of the above programs can be automatically generated by the command line tool For JSON format response, we create the controller as follows: /// The header file
#pragma once
#include <drogon/HttpSimpleController.h>
using namespace drogon;
class JsonCtrl : public drogon::HttpSimpleController<JsonCtrl>
{
public:
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);
} Let's go a step further and create a demo RESTful API with the HttpController class, as shown below (Omit the source file): /// 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 As you can see, users can use the In addition, you can also find that all handler interfaces are in asynchronous mode, where the response is returned by a callback object. This design is for performance reasons because in asynchronous mode the drogon application can handle a large number of concurrent requests with a small number of threads. After compiling all of the above source files, we get a very simple web application. This is a good start. For more information, please visit the wiki or DocsForge ContributionsEvery contribution is welcome. Please refer to the contribution guidelines for more information. |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论