Pistache 最简 HTTP 服务需正确初始化 Endpoint、设置路由处理器、调用 serve() 阻塞运行;路由为前缀匹配,不自动处理尾部斜杠或路径参数;需链接 -lpistache,避免旧版头文件缺失接口;JSON 解析需手动处理,大请求需调大 maxRequestSize;所有 handler 同线程执行,同步 IO 会阻塞事件循环。

如何用 Pistache 启动一个最简 HTTP 服务
能跑起来的最小代码不是靠抄示例,而是得理解 Pistache::Http::Endpoint 的生命周期和线程模型。它默认不阻塞主线程,但你得显式调用 serve() 才真正监听端口。
-
serve()是阻塞调用,写在main()最后一行即可;若提前返回,服务立即退出 - 端口被占用时,
serve()不抛异常,只默默失败——检查日志里有没有Failed to bind to port - 必须调用
setHandler()设置路由处理器,否则所有请求都返回 404(连 OPTIONS 都不响应) - 别漏掉
options.setFlags(Pistache::Tcp::Options::ReuseAddr),否则改代码重启时容易报Address already in use
#include <pistache/http.h>
using namespace Pistache;
int main() {
Address addr(Ipv4::any(), Port(9080));
Http::Endpoint server(addr);
auto opts = Http::Endpoint::options().threads(1);
server.init(opts);
server.setHandler(Http::make_router(
Http::Get("/ping") = [](const Http::Request&, Http::ResponseWriter writer) {
writer.send(Http::Code::Ok, "pong\n");
}
));
server.serve();
}
为什么路由匹配不到 /api/v1/users 这类带路径段的请求
Pistache 的路由是前缀匹配,不是完整路径匹配。写 Get("/api") 会同时匹配 /api、/api/、/api/v1/users,但不会自动拆分路径参数。
- 要捕获路径变量(如
/users/{id}),必须用Http::Router::route()+ 正则,原生make_router()不支持 - 如果写了
Get("/api/v1")却访问/api/v1/(末尾带斜杠),默认不匹配——Pistache 不自动处理 trailing slash - 静态文件服务需手动实现:读取
request.resource(),校验路径是否在允许目录内,再用sendFile()返回
编译时报错 undefined reference to `Pistache::Http::Endpoint::init 怎么办
这是链接阶段问题,不是头文件没包含。Pistache 分为 header-only 的基础部分和需要链接的网络实现部分。
- 必须链接
-lpistache,且顺序要在源文件之后(如g++ main.cpp -lpistache) - 如果用 CMake,确认
find_package(Pistache REQUIRED)成功,并在target_link_libraries()中加入Pistache::Pistache - Ubuntu 默认源里的
libpistache-dev版本太老(0.0.1),缺少setHandler()等接口,必须从 GitHub 源码编译安装 - macOS 上用 Homebrew 安装的 pistache 可能缺 OpenSSL 支持,导致 HTTPS 编译失败,需手动指定
-DUSE_SSL=ON
如何让 Pistache 正确解析 POST 的 JSON 请求体
request.body() 返回的是原始字节流,Pistache 不做任何解析。JSON 解析完全交由你选的库(如 nlohmann/json)处理。
立即学习“C++免费学习笔记(深入)”;
- 别假设
request.body()是 null-terminated 字符串——它只是std::string_view,长度由content-length决定 - Content-Type 必须是
application/json,否则前端发的 JSON 可能被当成纯文本,body 为空 - 大请求体(>1MB)可能触发默认限制,需在
Http::Endpoint::options()中设置.maxRequestSize() - 没有内置的表单解析,
application/x-www-form-urlencoded要自己用std::istringstream或第三方工具拆解
复杂点在于:Pistache 的异步模型是单线程事件循环,所有 handler 都在同一个线程执行。如果你在 handler 里做同步 IO(比如读文件、调数据库),整个服务就卡住。真要用,得把耗时操作扔进线程池,再用 Http::ResponseWriter::send() 异步回包——但这要求你管理 writer 生命周期,稍不注意就 use-after-free。











