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/