nexphant/server
Low-level HTTP socket server, request/response primitives, and high-performance router.
Install
composer require nexphant/serverHTTP Server
Instantiate HttpServer with a configuration array and pass it a Router:
use Nexphant\Server\HttpServer;
use Nexphant\Server\Router;
$router = new Router();
$router->get('/', function ($request, $response) {
$response->json(['ok' => true]);
});
$server = new HttpServer([
'host' => '0.0.0.0',
'port' => 8080,
'max_connections' => 500,
]);
$server->handle($router);
$server->start();Common server configuration keys:
| Key | Description |
|---|---|
host, port | Bind address. |
max_connections, backlog | Socket capacity and listen backlog. |
keep_alive_timeout, max_requests | Keep-alive behavior. |
runtime_safety, performance_mode | Dispatch and safety mode. |
event_loop, socket_driver | Runtime backend selection. |
max_accept_per_tick, max_read_callbacks_per_tick, max_write_callbacks_per_tick, max_deferred_per_tick | Event-loop fairness controls. |
graceful_shutdown_timeout | Drain timeout on shutdown. |
websocket_*, sse_* | WebSocket and SSE timeout, bus, Redis, replay, and backpressure settings. |
Routing & Parameters
Register handlers on Router for different HTTP methods. Parameters are injected into the $request attributes and passed as the third argument:
use Nexphant\Server\Router;
$router = new Router();
// Route with placeholder parameter
$router->get('/users/{id}', function ($request, $response, $params) {
$userId = $params['id'] ?? null;
$response->json(['user_id' => $userId]);
});
// Route groups
$router->group('/api', function (Router $r) {
$r->get('/health', function ($request, $response) {
$response->json(['status' => 'ok']);
});
});Middleware
Add middleware to the server pipeline. Middleware receives $request, $response, and route $params:
use Nexphant\Server\Middleware\Cors;
use Nexphant\Server\Middleware\RateLimit;
// Global middleware
$server->use(new Cors());
$server->use(new RateLimit(max: 100, window: 60));Request & Response API
Handlers write responses directly by modifying the passed $response object:
use Nexphant\Server\Request;
use Nexphant\Server\Response;
$router->post('/echo', function (Request $req, Response $res) {
// Read parsed JSON payload
$body = $req->json();
// Write JSON response
$res->json($body, status: 200);
});Common $response methods:
status(int $code): Set status code.header(string $name, string $value): Set header.body(string $body): Set response text body.json(mixed $data, int $status = 200): Format and send response as JSON.
Common $request methods:
| Method | Description |
|---|---|
header(string $name, ?string $default = null) | Read a normalized request header. |
query(string $name, mixed $default = null) | Read query string values lazily. |
post(string $name, mixed $default = null) | Read JSON or form body values. |
cookie(string $name, ?string $default = null) | Read cookies lazily. |
input(string $name, mixed $default = null) | Read body first, then query values. |
all() | Merge query and parsed body values. |
json() | Return parsed JSON body. |
isJson() | Check JSON content type. |
isMethod(string $method) | Compare request method. |
setAttribute, getAttribute, getAttributes | Store route and middleware attributes. |
Additional $response helpers:
| Method | Description |
|---|---|
headers(array $headers) | Set multiple headers. |
cookie(string $name, string $value, array $options = []) | Queue Set-Cookie. |
html(string $html, int $status = 200) | Send HTML. |
text(string $text, int $status = 200) | Send text. |
redirect(string $url, int $status = 302) | Send redirect. |
notFound(string $message = 'Not Found') | Send JSON 404. |
error(string $message, int $status = 500) | Send JSON error. |
rawHttp(string $response) | Send a prebuilt HTTP response. |
Serve Static Files
Configure serving directory for assets:
$server->use(new StaticFiles(base_path('public'), [
'max_age' => 86400,
'etag' => true,
'mime_types' => ['wasm' => 'application/wasm'],
]));StaticFiles handles GET and HEAD, rejects traversal attempts, serves index.html for directories, and emits ETag, Last-Modified, Cache-Control, and Content-Type headers.
Fast Responses
Register static hot-path responses directly on HttpServer:
$server->fastJson('GET', '/health', ['status' => 'ok']);
$server->fastText('GET', '/robots.txt', "User-agent: *\nAllow: /\n");
$server->fastRaw('GET', '/raw', $rawHttpResponse);
$server->fastCachedJson('GET', '/stats', fn () => ['uptime' => time()], ttl: 1);Fast routes bypass normal route dispatch for fixed paths. They are best for simple endpoints that return the same small payload often:
| Method | Use Case |
|---|---|
fastJson() | Health, readiness, version, and feature metadata. |
fastText() | Plain text assets such as robots.txt or lightweight probes. |
fastRaw() | Prebuilt HTTP responses. |
fastCachedJson() | Dynamic JSON that can be cached for a short TTL. |
Use normal router methods for paths with placeholders, request body parsing, per-route middleware, or controller dispatch.
Use RawResponseBuilder when a handler needs to return a prebuilt response:
use Nexphant\Server\RawResponse;
use Nexphant\Server\RawResponseBuilder;
return new RawResponse(RawResponseBuilder::json(200, ['ok' => true]));WebSocket and SSE
$server->onWebSocket('/chat',
onMessage: fn ($conn, string $message) => $server->sendWebSocket($conn, $message),
onOpen: fn ($conn) => $server->joinWebSocketRoom($conn, 'general'),
onClose: fn ($conn) => null,
);
$server->broadcastWebSocket('/chat', 'hello');
$server->broadcastWebSocketRoom('/chat', 'general', 'hello');For Server-Sent Events, start a stream from a request handler and broadcast later:
$server->startSse($request, $response, $request->getConnection());
$server->sendSse($connection, ['ping' => time()], event: 'ping');
$server->broadcastSse('/events', ['message' => 'updated']);Runtime Stats
$stats = $server->getStats();
$prometheus = $server->getMetricsText();
$server->gracefulShutdown();