Your server is running. Now build something.
Drop files in web/. Static files served from an in-memory cache, PHP scripts forked and executed. Add --workers=N for persistent workers with 100ร more concurrent capacity.
One process per connection. User isolation, auth, private state. Socket.IO compatible.
process per connectionOne process per room. Shared state for chat, games, collaboration. No Redis needed.
process per roomyour-project/ โโโ qbixserver.php โโโ config/ โ โโโ server.json โ optional config โโโ web/ โ document root โ โโโ index.html โ replaces this page โ โโโ api/hello.php โ HTTP endpoint โโโ handlers/ โ WebSocket + room handlers โ โโโ chat/ โ โ โโโ join.php โ per-connection โ โ โโโ room/ โ โ โโโ join.php โ room lifecycle โ โ โโโ message.php โ room event โ โ โโโ leave.php โ โโโ connect.php โ on WebSocket connect โโโ classes/ โ autoloaded โ โโโ ChatRoom.php โ shared room state โโโ errors/ โ custom error pages (optional) โโโ 404.php
Any file in web/ is served. PHP files are executed in a forked process.
<?php
// web/api/hello.php โ visit /api/hello.php?name=Alice
Q_WebServer_State::header('Content-Type: application/json');
echo json_encode([
'message' => 'Hello, ' . ($_GET['name'] ?? 'world')
]);
Each connection gets its own process. Configure in config/server.json:
{
"Q": {
"webserver": {
"sockets": {
"events": {
"_connect": "connect",
"chat/join": "chat/join"
},
"rooms": {
"chat/$room": {"handler": "chat/room"}
}
}
}
}
}
<?php
// handlers/chat/join.php
function chat_join(&$params, &$result) {
extract($params); // $socket, $event, $data
$socket->join('chat/' . $data['room'], [
'name' => $data['name']
]);
$result = ['joined' => $data['room']];
}
All members share one process. State lives in class statics.
<?php
// handlers/chat/room/message.php
function chat_room_message(&$params, &$result) {
extract($params); // $room, $event, $data
$name = ChatRoom::$names[$room->socketId] ?? 'anon';
$room->broadcast([
'event' => 'chat/message',
'data' => ['name' => $name, 'text' => $data['text']]
]);
}
<script src="/socket.io/socket.io.js"></script>
<script>
const socket = io({transports: ['websocket']});
socket.emit('chat/join', {room: 'general', name: 'Alice'});
socket.on('chat/message', (d) => console.log(d.name + ': ' + d.text));
socket.emit('chat/message', {text: 'Hello!'});
</script>
web/index.html to replace this page. Read the Getting Started guide for the full walkthrough.
web/index.html replaces this page