OAT++教程1 環境的安裝.docx
最近工作的項目中使用了OAT++的c++框架實現web客戶端和服務器的通信,雖然整個開發過程已經不需要自己做什麼配置,只需要按照商定的接口寫好內部邏輯。但是整個框架的搭建和運作模式還是引起了我的興趣,所以想通過這一系列教程來提高自己對OAT++框架的認識。
在這塊磐石之上,我要建立我的教會。萬丈高樓平地起,我們先看看如何在Linux下把環境配置起來。
這裏假設你的環境已經有了git,較新版本的gcc(其實只要支持c++11就可以了),還有cmake.
- 首先是獲取源碼,以及編譯
git clone https://github.com/oatpp/oatpp.git cd oatpp/ mkdir build && cd build cmake .. make
這裏是我們使用CMakeLists.txt編譯的老套路了,如果你經常使用CMakeLists.txt,就會知道這裏沒有什麼新東西
2. 接下來和oatpp官網上的教程有一些不同,我自己在搭建環境的過程中喜歡儘可能簡單一些,傻瓜一些。
a. 在第一步創建的build目錄下,把
src/liboatpp.a src/liboatpp-test.a 這兩個編出來的庫拷貝到/usr/lib/目錄下
b.進入到代碼的src目錄,把src下的oatpp整個文件夾拷貝到/usr/include/目錄下
整個安裝過程就完成了,這樣安裝的好處就是過程比較簡單,之後你需要用到oatpp相關頭文件時候用<>包含就可以了。
現在我們用一個簡單的程序來檢查一下搭建的環境是否可用:
|- CMakeLists.txt // projects CMakeLists.txt
|- main.cpp
按照上圖的的目錄結構創建文件。
文件main.cpp的內容如下:
#include <oatpp/parser/json/mapping/ObjectMapper.hpp>
#include <oatpp/web/server/HttpConnectionHandler.hpp>
#include <oatpp/network/server/Server.hpp>
#include <oatpp/network/server/SimpleTCPConnectionProvider.hpp>
#include <oatpp/core/macro/codegen.hpp>
/* Begin DTO code-generation */
#include OATPP_CODEGEN_BEGIN(DTO)
/**
* Message Data-Transfer-Object
*/
class MessageDto : public oatpp::data::mapping::type::Object {
DTO_INIT(MessageDto, Object /* Extends */)
DTO_FIELD(Int32, statusCode); // Status code field
DTO_FIELD(String, message); // Message field
DTO_FIELD(String, name, "First-Name");
DTO_FIELD(String, surname, "Family-Name");
};
class MessageWorldDto : public oatpp::data::mapping::type::Object {
DTO_INIT(MessageWorldDto, Object /* Extends */)
DTO_FIELD(Int32, statusCode); // Status code field
DTO_FIELD(String, message); // Message field
};
/* End DTO code-generation */
#include OATPP_CODEGEN_END(DTO)
/**
* Custom Request Handler
*/
class Handler : public oatpp::web::server::HttpRequestHandler {
private:
std::shared_ptr<oatpp::data::mapping::ObjectMapper> m_objectMapper;
public:
/**
* Constructor with object mapper.
* @param objectMapper - object mapper used to serialize objects.
*/
Handler(const std::shared_ptr<oatpp::data::mapping::ObjectMapper>& objectMapper)
: m_objectMapper(objectMapper)
{}
/**
* Handle incoming request and return outgoing response.
*/
std::shared_ptr<OutgoingResponse> handle(const std::shared_ptr<IncomingRequest>& request) override {
auto message = MessageDto::createShared();
message->statusCode = 1024;
message->message = "Hello DTO!";
message->name = "Tom";
message->surname = "Jerry";
return ResponseFactory::createResponse(Status::CODE_200, message, m_objectMapper.get());
}
};
class WorldHandler : public oatpp::web::server::HttpRequestHandler {
private:
std::shared_ptr<oatpp::data::mapping::ObjectMapper> m_objectMapper;
public:
/**
* Constructor with object mapper.
* @param objectMapper - object mapper used to serialize objects.
*/
WorldHandler(const std::shared_ptr<oatpp::data::mapping::ObjectMapper>& objectMapper)
: m_objectMapper(objectMapper)
{}
/**
* Handle incoming request and return outgoing response.
*/
std::shared_ptr<OutgoingResponse> handle(const std::shared_ptr<IncomingRequest>& request) override {
auto message = MessageWorldDto::createShared();
message->statusCode = 1024;
message->message = "World is fine!";
return ResponseFactory::createResponse(Status::CODE_200, message, m_objectMapper.get());
}
};
void run() {
/* Create json object mapper */
auto objectMapper = oatpp::parser::json::mapping::ObjectMapper::createShared();
/* Create Router for HTTP requests routing */
auto router = oatpp::web::server::HttpRouter::createShared();
/* Route GET - "/hello" requests to Handler */
router->route("GET", "/hello", std::make_shared<Handler>(objectMapper /* json object mapper */ ));
router->route("GET", "/world", std::make_shared<WorldHandler>(objectMapper /* json object mapper */ ));
/* Create HTTP connection handler with router */
auto connectionHandler = oatpp::web::server::HttpConnectionHandler::createShared(router);
/* Create TCP connection provider */
auto connectionProvider = oatpp::network::server::SimpleTCPConnectionProvider::createShared(10000 /* port */);
/* Create server which takes provided TCP connections and passes them to HTTP connection handler */
oatpp::network::server::Server server(connectionProvider, connectionHandler);
/* Priny info about server port */
OATPP_LOGI("MyApp", "Server running on port %s", connectionProvider->getProperty("port").getData());
/* Run server */
server.run();
}
int main() {
/* Init oatpp Environment */
oatpp::base::Environment::init();
/* Run App */
run();
/* Destroy oatpp Environment */
oatpp::base::Environment::destroy();
return 0;
}
可以看到這個web服務器佔用的端口號是10000
現在準備CMakeList.txt
cmake_minimum_required(VERSION 3.7.2)
project(Trunk)
set(CMAKE_CXX_STANDARD 11)
add_executable(Trunk main.cpp)
target_link_libraries(Trunk
pthread
oatpp
)
使用前面的老方法在示例代碼的目錄下編譯:
mkdir build && cd build
cmake ..
make
順利的話object Trunk 已經在build目錄下生成了。
用命令 ./Trunk & 運行,觀察Hello world級的程序是否正常工作。
首先可以看到類似這樣的打印,說明服務已經起來了。
I |2020-01-14 21:05:58 1579007158312275| MyApp:Server running on port 10000
現在看看能不能提供服務
在瀏覽器輸入:http://127.0.0.1:10000/world或者直接執行命令curl http://127.0.0.1:10000/world,都可以看到同樣的結果:
{"statusCode":1024,"message":"World is fine!"}
這說明我們的環境搭建成功,一個簡單的c++ web服務器已經運行起來了。
更加詳細的教程請見 OATPP 官網 https://oatpp.io/docs/start/project/