TrueAsync\HttpServer
(PHP 8.6+, true_async_server 0.6+)
Главный класс встроенного сервера. Получает конфиг через конструктор, принимает обработчики протоколов, запускается через start() и блокирует поток до stop().
namespace TrueAsync;
final class HttpServer
{
public function __construct(HttpServerConfig $config);
public function addHttpHandler(callable $handler): static;
public function addStaticHandler(StaticHandler $handler): static;
public function addWebSocketHandler(callable $handler): static; // TODO
public function addHttp2Handler(callable $handler): static; // TODO
public function addGrpcHandler(callable $handler): static; // TODO
public function start(): bool;
public function stop(): bool;
public function isRunning(): bool;
public function getConfig(): HttpServerConfig;
public function getHttp3Stats(): array;
public function getRuntimeStats(): array;
public function getTelemetry(): array; // TODO
public function resetTelemetry(): bool; // TODO
}Методы
__construct
public HttpServer::__construct(HttpServerConfig $config)Создаёт сервер с заданным конфигом. Конфиг замораживается на этом вызове — последующие сеттеры бросают HttpServerRuntimeException.
addHttpHandler
public HttpServer::addHttpHandler(callable $handler): staticРегистрирует обработчик HTTP/1.1 и HTTP/2 запросов. Сигнатура:
function (HttpRequest $request, HttpResponse $response): voidКаждый запрос выполняется в собственной корутине в per-request scope. Обработчик возвращает void; ответ отправляется через $response.
addStaticHandler
public HttpServer::addStaticHandler(StaticHandler $handler): staticРегистрирует static-mount (issue #13). Запросы под $handler->getUrlPrefix() обслуживаются полностью в C — без спавна корутины, без захода в PHP VM.
Множественные mount'ы матчатся в порядке регистрации. После attach handler блокируется — любые сеттеры на нём бросают HttpServerRuntimeException.
См. StaticHandler.
addWebSocketHandler
public HttpServer::addWebSocketHandler(callable $handler): static📋 Запланировано. RFC 6455, upgrade с HTTP/1.1 и HTTP/2.
addHttp2Handler
public HttpServer::addHttp2Handler(callable $handler): static📋 Запланировано. Сейчас HTTP/2 запросы попадают в addHttpHandler (общий H1/H2 диспетчер).
addGrpcHandler
public HttpServer::addGrpcHandler(callable $handler): static📋 Запланировано. Поверх HTTP/2, unary и streaming RPC.
start
public HttpServer::start(): boolЗапускает сервер и блокирует вызывающий поток до stop() или фатальной ошибки.
- При
setWorkers(1)— крутит event-loop на вызывающем потоке. - При
setWorkers(N > 1)— спавнитAsync\ThreadPoolиз N воркеров иawaitит их завершение.
Возвращает true при штатной остановке. Бросает HttpServerException (и наследников) при ошибках запуска (bind failed, отсутствует требуемая сборка для HTTP/3 при наличии addHttp3Listener и т.п.).
stop
public HttpServer::stop(): boolGraceful shutdown:
- Прекращает приём новых соединений.
- Ждёт завершения активных запросов (до
setShutdownTimeout()). - Закрывает все соединения.
Возвращает true при успешной остановке.
Cross-thread
stop()— в roadmap. Сейчас остановку чаще всего инициируют через SIGINT/SIGTERM.
isRunning
public HttpServer::isRunning(): boolgetConfig
public HttpServer::getConfig(): HttpServerConfigВозвращает тот же объект конфига, что был передан в __construct. После старта сервера конфиг заблокирован (isLocked() === true).
getHttp3Stats
public HttpServer::getHttp3Stats(): arrayPer-listener observability для HTTP/3. Одна запись на каждый addHttp3Listener() в порядке регистрации. Каждая запись содержит:
| Ключ | Значение |
|---|---|
host | привязанный host |
port | UDP-порт |
datagrams_received | счётчик пришедших датаграмм |
bytes_received | байтов принято |
datagrams_errored | датаграмм с ошибкой |
last_datagram_size | размер последней датаграммы |
last_peer | последний peer (string) |
Возвращает пустой массив, когда расширение собрано без --enable-http3.
getRuntimeStats
public HttpServer::getRuntimeStats(): arraySnapshot внутренних аллокаторов сервера. Помогает атрибутировать рост RSS на конкретные подсистемы.
| Ключ | Что значит |
|---|---|
conn_arena_live | http_connection_t слотов сейчас в работе (один на live TCP-connection) |
conn_arena_slots | всего слотов в чанках (live + free, не shrink'ается) |
conn_arena_chunks | сколько чанков закоммичено; каждый — CONN_ARENA_CHUNK_SLOTS (256) структур по ~768 B |
conn_arena_bytes | chunks × 256 × sizeof(http_connection_t) — виртуальная commitment |
body_pool | per-size-class LIFO крупных request-bodies (1 MB..128 MB). Каждая запись: slot_bytes, count, bytes |
body_pool_total_bytes | сумма bytes по всем классам |
getTelemetry
public HttpServer::getTelemetry(): array📋 Запланировано.
resetTelemetry
public HttpServer::resetTelemetry(): bool📋 Запланировано.
Пример
use TrueAsync\HttpServer;
use TrueAsync\HttpServerConfig;
use TrueAsync\StaticHandler;
$server = new HttpServer(
(new HttpServerConfig())
->addListener('0.0.0.0', 8080)
->setWorkers(4)
);
$server->addStaticHandler(
(new StaticHandler('/assets/', __DIR__ . '/public'))
->enablePrecompressed('br', 'gzip')
);
$server->addHttpHandler(function ($req, $res) {
$res->json(['ok' => true, 'path' => $req->getPath()]);
});
$server->start();