oaptt搭建http服务的过程详解
时间:2023-03-21 09:47:40|栏目:C代码|点击: 次
Oat++ 介绍
Oat++ 主页:https://oatpp.io
Oat++ 文档:https://oatpp.io/docs/start
GitHub 地址:https://github.com/oatpp/oatpp
编译 Oat++
环境要求
Oat++ 的编译过程很简单,只需要有基本的开发环境就行了:
- Git
- 编译器支持的 C++ 版本 >= 11
- Make
- CMake 版本 >= 3.1
如果没有的话,按照下述步骤安装,以 Ubuntu 为例:
sudo apt install git sudo apt install cmake sudo apt install build-essential
编译安装
下载 Oat++ 源码:
git clone https://github.com/oatpp/oatpp.git
随后,执行编译安装四部曲:
cd oatpp/ mkdir build && cd build cmake .. sudo make && sudo make install
hello示例程序
为了演示 Oat++,我们从最简单的“Hello, World!”
开始!
创建一个 CMake 项目,CMakeLists.txt 配置
如下:
cmake_minimum_required(VERSION 3.1) project(helloworld) set(CMAKE_CXX_STANDARD 11) set(SOURCE_FILES main.cpp handler.h) # 查找 oatpp 依赖 find_package(oatpp REQUIRED) add_executable(${PROJECT_NAME} ${SOURCE_FILES}) # 将目标文件与库文件进行链接 target_link_libraries(${PROJECT_NAME} oatpp::oatpp)
handler.h
// handler.h #ifndef HANDLER_H #define HANDLER_H #include "oatpp/web/server/HttpRequestHandler.hpp" #define O_UNUSED(x) (void)x; // 自定义请求处理程序 class Handler : public oatpp::web::server::HttpRequestHandler { public: // 处理传入的请求,并返回响应 std::shared_ptr<OutgoingResponse> handle(const std::shared_ptr<IncomingRequest>& request) override { O_UNUSED(request); return ResponseFactory::createResponse(Status::CODE_200, "Hello, World!"); } }; #endif // HANDLER_H
main.cpp
// main.cpp #include "oatpp/web/server/HttpConnectionHandler.hpp" #include "oatpp/network/tcp/server/ConnectionProvider.hpp" #include "oatpp/network/Server.hpp" #include "handler.h" void run() { // 为 HTTP 请求创建路由器 auto router = oatpp::web::server::HttpRouter::createShared(); // 路由 GET - "/hello" 请求到处理程序 router->route("GET", "/hello", std::make_shared<Handler>()); // 创建 HTTP 连接处理程序 auto connectionHandler = oatpp::web::server::HttpConnectionHandler::createShared(router); // 创建 TCP 连接提供者 auto connectionProvider = oatpp::network::tcp::server::ConnectionProvider::createShared({"0.0.0.0", 8080, oatpp::network::Address::IP_4}); // 创建服务器,它接受提供的 TCP 连接并将其传递给 HTTP 连接处理程序 oatpp::network::Server server(connectionProvider, connectionHandler); // 打印服务器端口 OATPP_LOGI("MyApp", "Server running on port %s", connectionProvider->getProperty("port").getData()); // 运行服务器 server.run(); } int main() // 初始化 oatpp 环境 oatpp::base::Environment::init(); // 运行应用 run(); // 销毁 oatpp 环境 oatpp::base::Environment::destroy(); return 0;
编译helloworld程序
mkdir build cd build cmake .. make ./helloworld
运行结果如下
HTTP模拟Onvif功能
启动HTTP服务器模拟Onvif服务端,接收Onvif客户端发送过来的http请求并响应xml数据
项目背景 和 解决方案 点 这里
CMakeList.txt
cmake_minimum_required(VERSION 3.1) project(helloworld) set(CMAKE_CXX_STANDARD 11) set(SOURCE_FILES main.cpp handler.h) # 查找 oatpp 依赖 find_package(oatpp REQUIRED) add_executable(${PROJECT_NAME} ${SOURCE_FILES}) # 将目标文件与库文件进行链接 target_link_libraries(${PROJECT_NAME} oatpp::oatpp)
handler.h
// handler.h #ifndef HANDLER_H #define HANDLER_H #include "oatpp/web/server/HttpRequestHandler.hpp" #include "oatpp/web/protocol/http/incoming/Response.hpp" #include<fcntl.h> #include<unistd.h> #include <sys/stat.h> #include <unistd.h> #define O_UNUSED(x) (void)x; #define XML_INFO "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\" ?>" // 自定义请求处理程序 class Handler : public oatpp::web::server::HttpRequestHandler { public: // 处理传入的请求,并返回响应 std::shared_ptr<OutgoingResponse> handle(const std::shared_ptr<IncomingRequest>& request) override { // O_UNUSED(request); OATPP_LOGI("MyApp", "new connect.."); // printf("method:%d"); int fileFd = open("../test.xml",O_RDONLY); if(fileFd < 0) return 0; //获取文件大小 struct stat fileStat; fstat(fileFd, &fileStat); int fileSize = fileStat.st_size; printf("fd:%d ,file size %d\n ", fileFd ,fileStat.st_size); //申请空间存储xml数据 char buf[1024 * 5]; memset(buf,'\0',sizeof(buf)); read(fileFd,buf,sizeof(buf)); printf("new connect..\n"); printf("buf:%s\n\n",buf); //创建响应并添加请求头 std::shared_ptr<OutgoingResponse> resp = ResponseFactory::createResponse(Status::CODE_200, buf); resp->putHeader("Content-Type","application/soap+xml; charset=utf-8; action=\"http://www.onvif.org/ver20/media/wsdl/GetOSDs\""); // resp->putHeader("charset","utf-8"); // resp->putHeader("action","\"http://www.onvif.org/ver20/media/wsdl/GetOSDs\""); resp->putHeader("X-Frame-Options","SAMEORIGIN"); close(fileFd); return resp; //响应请求 } }; #endif // HANDLER_H
main.cpp
// main.cpp #include "oatpp/web/server/HttpConnectionHandler.hpp" #include "oatpp/network/tcp/server/ConnectionProvider.hpp" #include "oatpp/network/Server.hpp" #include "handler.h" void run() { // 为 HTTP 请求创建路由器 auto router = oatpp::web::server::HttpRouter::createShared(); // 路由 GET - "/hello" 请求到处理程序 router->route("POST", "/onvif/Media2", std::make_shared<Handler>()); // 创建 HTTP 连接处理程序 auto connectionHandler = oatpp::web::server::HttpConnectionHandler::createShared(router); // 创建 TCP 连接提供者 auto connectionProvider = oatpp::network::tcp::server::ConnectionProvider::createShared({"0.0.0.0", 7681, oatpp::network::Address::IP_4}); // 创建服务器,它接受提供的 TCP 连接并将其传递给 HTTP 连接处理程序 oatpp::network::Server server(connectionProvider, connectionHandler); // 打印服务器端口 OATPP_LOGI("MyApp", "Server running on port %s", connectionProvider->getProperty("port").getData()); // 运行服务器 server.run(); } int main() // 初始化 oatpp 环境 oatpp::base::Environment::init(); // 运行应用 run(); // 销毁 oatpp 环境 oatpp::base::Environment::destroy(); return 0;
test.xml
<?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Header></SOAP-ENV:Header> <SOAP-ENV:Body> <media2:GetOSDsResponse> </media2:GetOSDsResponse> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
与helloworld程序的主要区别就是添加了一些请求头以及发送xml数据