- 作者
- 赵曦
- 日期
- 2025/09/25
- 版本
- 1.0
上一篇教程:传输层设施 —— Socket
下一篇教程:工业自动化通信协议 —— OPC UA
相关类
1 HTTP 数据结构
相关类: rm::Request 及 rm::Response
两个类均提供了
- generate 成员函数,用于从请求/响应结构生成 HTTP 格式的字符串,在调用此方法后可直接通过 Socket 发送数据
- parse 静态成员函数,用于从 HTTP 格式的字符串解析出请求/响应结构,在接收到 Socket 原始数据后可调用此方法进行解析
rm::Response 还提供了多种简化生成响应的成员函数,如 send、json、redirect 等。
2 HTTP 请求工具
相关函数:
设计理念参考 Python 的 requests 库,提供了极其简洁易用的接口,这里给出一个简单的 GET 请求示例:
#include <rmvl/io/netapp.hpp>
int main() {
if (response) {
printf("Response: %s\n", response->body().c_str());
}
}
Response get(std::string_view url, const std::vector< std::string > &querys={}, const std::unordered_map< std::string, std::string > &heads={})
发出同步 GET 请求
定义 netapp.hpp:282
异步请求的使用方法类似,只需将 requests 替换为 async::requests,并在协程中使用 co_await 关键字等待结果,这里不再赘述。
3 Web 后端框架
RMVL 提供了后端应用框架 rm::async::Webapp ,以及负责传输层监听的 rm::async::HttpServer 和 rm::async::HttpsServer 。设计参考 Express JS,具体来说,Webapp 负责路由与中间件,服务器对象负责 HTTP 或 HTTPS 监听,同一个 Webapp 可以交给不同类型的服务器。
3.1 HTTP 服务器
rm::async::Webapp 和 rm::Router 提供了 GET、POST、DELETE 等相关方法用于定义路由,并且 rm::async::Webapp 可以使用 use 方法挂载中间件或挂载由 rm::Router 定义的子路由。
#include <rmvl/io/netapp.hpp>
int main(int argc, char *argv[]) {
if (argc < 2) {
printf("Usage: %s <port>\n", argv[0]);
return 1;
}
uint16_t port = static_cast<uint16_t>(std::atoi(argv[1]));
res.
send(
"<html><body><h1>Hello, World!</h1></body></html>");
});
});
{"key", "value"},
{"message", "This is a test API."},
});
});
auto name = req.
params.at(
"name");
{"greeting", "Hello, " + name + "!"},
});
});
app.use("/api", api_router);
server.listen(port, [&]() {
printf("Server is running on port %d\n", port);
});
}
HTTP 与 WebSocket 请求路由
定义 netapp.hpp:409
void get(std::string_view uri, RouteHandler callback)
Get 请求路由
定义 netapp.hpp:461
HTTP 服务器
定义 netapp.hpp:727
异步 I/O 执行上下文,负责管理 IO 事件循环和协程任务的调度
定义 async.hpp:187
Web 应用程序框架
定义 netapp.hpp:589
ResponseMiddleware cors()
【中间件】跨域资源共享 CORS,为响应添加 CORS 头部信息
void co_spawn(IOContext &ctx, Callable &&fn, Args &&...args)
在指定的执行上下文中生成并调度一个协程任务
定义 async.hpp:282
HTTP 请求结构
定义 netapp.hpp:75
std::unordered_map< std::string, std::string > params
路径参数
定义 netapp.hpp:94
HTTP 响应结构
定义 netapp.hpp:109
Response & json(const ::rm::json &j)
发送 JSON 格式的响应数据
Response & redirect(std::string_view url)
发送重定向响应
定义 netapp.hpp:169
Response & send(std::string_view str)
发送响应数据
可以简单使用以下命令行进行编译
g++ demo.cpp /usr/local/include/RMVL rmvl_io rmvl_core demo
- 注解
- 当然,也可以自行编写 CMakeLists.txt 文件,采用 CMake 构建系统进行构建,具体的 CMakeLists.txt 内容可参考如下内容:
cmake_minimum_required(VERSION 3.16)
project(Demo)
find_package(RMVL REQUIRED)
rmvl_add_exe(
demo
SOURCES demo.cpp
DEPENDS io
)
编译后,在终端输入
即可创建 Web 后端服务,并且监听 8080 端口,可以使用 curl 工具或浏览器访问 http://localhost:8080/ 来测试服务器。
curl "http://localhost:8080"
会得到如下输出:
htmlbodyh1Hello, World!/h1/body/html
- 注解
- rm::async::Webapp 虽然也提供了 listen 方法,但该方法仅用于快速测试,实际生产环境推荐使用 rm::async::HttpServer 或 rm::async::HttpsServer 进行监听。
3.2 HTTPS 服务器
HTTPS 与 HTTP 使用相同的 Webapp,只需要将 rm::async::HttpServer 替换为 rm::async::HttpsServer ,并提供服务端的 rm::SSLContext 即可,示例代码如下:
res.
send(
"Hello, HTTPS!");
});
if (!ssl_context.
load_cert(
"server.crt",
"server.key")) {
printf(
"%s\n", ssl_context.
lasterr().c_str());
return 1;
}
server.listen(8443, [] {
printf("HTTPS server is listening on 8443\n");
});
std::string lasterr() const
获取最近一次错误信息
定义 ssl.hpp:74
bool load_cert(std::string_view cert_file, std::string_view key_file)
加载证书与私钥文件
static SSLContext server()
创建服务端 TLS 上下文
定义 ssl.hpp:65
HTTPS 服务器
定义 netapp.hpp:771
SSLContext 必须比 HttpsServer 和所有活动 TLS 连接存活得更久。证书自动续期后,需要重新加载 SSLContext 或重启/重载服务进程,才能让新连接使用更新后的证书。 使用命令行直接编译 HTTPS 程序时,还需要链接 OpenSSL 的 ssl 和 crypto 库;使用 CMake 链接 rmvl_io 目标时会自动传递该依赖。
测试自签名证书时可以使用:
curl "https://127.0.0.1:8443/"