Pistacheによる軽量なHTTPサーバー実装
Pistacheは、C++で動作する高パフォーマンスな非同期HTTPフレームワークであり、ヘッダーのみのライブラリではない。完全なサーバー機能を備え、マルチスレッド対応やHTTPSサポートも提供している。
基本的なレスポンスコードの使用例
- 正常応答:HTTPステータス200(OK)でデータを返す場合
response.send(Http::Code::Ok, data.c_str());
response.send(Http::Code::No_Content, "e_tunnel_locInfoが空です");
catch (const std::exception& e) {
response.send(Http::Code::Expectation_Failed, e.what());
}
サーバー起動の条件分岐
設定ファイルに基づき、HTTPサービスの有効/無効を切り替える実装。
if (hzi::config.enable_http) {
std::thread(start_http_server).join();
} else {
std::thread(sse::startConfRelayer).detach();
std::thread(sse::startSSERelayer).join();
}
ルート定義:routes.hpp
#ifndef ROUTES_HPP
#define ROUTES_HPP
#include <pistache/endpoint.h>
#include <pistache/router.h>
using namespace Pistache;
using namespace Rest;
class RouteHandler : public Http::Endpoint {
Rest::Router router;
public:
explicit RouteHandler(Address addr);
};
#endif
ルートマッピング:routes.cpp
#include "routes.hpp"
RouteHandler::RouteHandler(Address addr) : Http::Endpoint(addr) {
Routes::Get(router, "/firstChnNO", Routes::bind(&ms_comm::fetchFirstChannel));
// 他のエンドポイントも同様に追加
setHandler(router.handler());
}
コールバック関数の実装:ms_commands.cpp
namespace ms_comm {
void fetchFirstChannel(const Rest::Request& req, Http::ResponseWriter res) {
try {
res.headers().add("text/plain; charset=utf-8");
res.send(Http::Code::Ok, std::to_string(hzi::firstChnNO).c_str());
} catch (const std::exception& e) {
res.send(Http::Code::Bad_Request, e.what());
}
}
}
HTTPサーバーの初期化:http_server.cpp
void start_http_server() {
const Address listen_addr{Ipv4::any(), hzi::config.httpPort};
RouteHandler server(listen_addr);
logInfo("HTTPサーバーをポート " + std::to_string(hzi::config.httpPort) + " で起動");
const unsigned int core_count = std::thread::hardware_concurrency();
auto options = Pistache::Http::Endpoint::options()
.maxRequestSize(5 * 1024 * 1024) // 最大リクエストサイズ:5MB
.threads(core_count / 2) // スレッド数をハードウェアコア数の半分に制限
.flags(Pistache::Tcp::Options::ReuseAddr); // 再利用可能なアドレス許可
server.init(options);
server.useSSL("etc/cert/server.pem", "etc/cert/server.key"); // HTTPS対応
server.serve(); // サーバー開始、リクエスト待機
}