- 接口简单易用
#include "http/server.hpp"
http::server server{8080, 8}; //8 threads
server.get("/hello", [](const http::request &) {
http::response res;
res.status = http::status_type::ok; //200
res.content.emplace<std::string>("<h1>Hello world!</h1>");
return res;
});
//协程作为回调函数
server.get("/login", [](const http::request &req) -> http::task<http::response>{//C++标准要求,协程必须显式指定返回类型。
http::response res;
auto session = co_await /*数据库操作*/
...
co_return res;
});
//正则表达式
server.get("/.*\\.html", [](const http::request &req) -> http::task<http::response> {
http::response res;
res.status = http::status_type::ok;
res.headers.insert({"Content-Type", "text/html"});
res.content.emplace<std::filesystem::path>(std::string{R"(../public)"} + req.url);
co_return res;
});
//websocket
server.websocket("/echo", [ ](http::ws_stream stream)->http::task<void> {
while (true) {
std::string msg;
boost::asio::dynamic_string_buffer buffer{ msg, 1 << 16 };
std::tuple<boost::system::error_code> ret = co_await stream.async_read(buffer);
if (std::get<0>(ret))
co_return;
stream.send(std::make_shared<std::string>(std::move(msg)));
}
});
//subscribe-publish
server.websocket("/chat-room", [ ](http::ws_stream stream)->http::task<void> {
stream.join("chat"); //join in a room named "chat"
while (true) {
auto msg = std::make_shared<std::string>();
msg->reserve(128);
boost::asio::dynamic_string_buffer buffer{ *msg, 1 << 16 };
auto ret = co_await stream.async_read(buffer);
if(std::get<0>(ret))
co_return; //automatic call stream.leave() to leave room
/*
* deal with message
*/
stream.room().publish(msg);
}
});
server.listen();
- 高性能:使用 IOCP 或 io_uring,小文件传输 1万 QPS,速率 1.2 GB /s,大文件传输速率高达 2 GB /s
Server Software: | |||
---|---|---|---|
Server Hostname: | 127.0.0.1 | ||
Server Port: | 8080 | ||
Document Path: | /girl.jpeg | ||
Document Length: | 119513 bytes | ||
Concurrency Level: | 100 | ||
Time taken for tests: | 9.576 seconds | ||
Complete requests: | 100000 | ||
Failed requests: | 0 | ||
Total transferred: | 11955800000 bytes | ||
HTML transferred: | 11951300000 bytes | ||
Requests per second: | 10442.85 | ||
Transfer rate: | 1219264.17 kB/s received | ||
Connection Times (ms) | |||
min | avg | max | |
Connect: | 0 | 0 | 10 |
Processing: | 6 | 9 | 216 |
Total: | 6 | 9 | 226 |
Server Software: | |||
---|---|---|---|
Server Hostname: | 127.0.0.1 | ||
Server Port: | 8080 | ||
Document Path: | /girl.mp4 | ||
Document Length: | 11165483 bytes | ||
Concurrency Level: | 10 | ||
Time taken for tests: | 4.964 seconds | ||
Complete requests: | 1000 | ||
Failed requests: | 0 | ||
Total transferred: | 11165527000 bytes | ||
HTML transferred: | 11165483000 bytes | ||
Requests per second: | 201.44 | ||
Transfer rate: | 2196434.60 kB/s received | ||
Connection Times (ms) | |||
min | avg | max | |
Connect: | 0 | 0 | 2 |
Processing: | 42 | 49 | 66 |
Total: | 42 | 49 | 68 |
Linux 下依赖liburing,内核版本5.15以上, 低于5.15使用epoll和线程池(文件IO)
git clone https://github.com/axboe/liburing.git
cd liburing
./configure
make install
CMakeLists.txt
cmake_minimum_required(VERSION 3.20)
project(yourproject)
set(CMAKE_CXX_STANDARD 20) #支持协程
find_package(Boost 1.80.0 REQUIRED) #依赖boost库,Linux下要求v1.78以上(io_uring)
include_directories(${Boost_INCLUDE_DIR})
add_subdirectory(http)
add_executable(yourproject ...)
target_link_libraries(yourproject http)
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make
./http-server
http://localhost:8080/index.html
ab -n 1000 -c 10 http://127.0.0.1/girl.mp4