From 8d44599e1ee045cb20e32c2832fc3120e76f414d Mon Sep 17 00:00:00 2001 From: Gregory Magarshak Date: Tue, 21 Jul 2026 18:34:26 -0400 Subject: [PATCH] Added socket->disconnect() method for use by child processes --- README.md | 13 ++++++++++++- bin/qbixserver.phar | Bin 366016 -> 366215 bytes src/Q.php | 3 +++ src/Q/WebSocket.php | 3 +++ 4 files changed, 18 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0b175c6..6a67233 100644 --- a/README.md +++ b/README.md @@ -766,6 +766,7 @@ function chat_message(&$params, &$result) { | `$socket->broadcastAll($data)` | Send to ALL connected clients | | `$socket->join($room, $data)` | Join a room, forwarding `$data` to the room's join handler | | `$socket->leave($room, $data)` | Leave a room, forwarding `$data` to the room's leave handler | +| `$socket->disconnect()` | Close this connection | | `$socket->anyMethod($data)` | **RPC** — calls a method on the client, blocks until response (5s timeout) | **Room handlers** get `$room` — a `Q_Room` instance: @@ -2170,7 +2171,17 @@ Changes are logged to stderr: 14:32:09 hot-reload: restarting server... ``` -Polls every 2 seconds. Use in development, not production. +Polls every 2 seconds. Recommended for development. + +Even without `--hotreload`, handler changes take effect naturally: HTTP +requests fork fresh and load handlers on demand, so the next request gets the +new file. WebSocket connections and rooms keep the old code for their lifetime +— new connections pick up the change. A natural rolling deploy with no +interruption. The `--hotreload` flag adds automatic restart for class and +config changes, which are preloaded in the parent process. + +If `Q.handlers.preload` is `true` (production mode), handlers are also loaded +in the parent — use `--reload` to pick up handler changes in that case. ### Scheduler diff --git a/bin/qbixserver.phar b/bin/qbixserver.phar index 3f7e2f6f105ca588056bd4dcd12d92ad92429a2d..4d67984064baccd1497aa416d45682f16d267750 100755 GIT binary patch delta 226 zcmX@GTC9Do*oGC{0!al7U;v`^&CQZF@8B+B6!7STh=S->8&526w&88J;bq)z!^`xp zoi8P`I5|HrFEzPD-HMBIy1xaJC~tCZO0;@$esXqdiDyc?;8Z3cX5KD1l|^N@fr1NM zgF;D0X0bwYPG)LeiGr3s7iU^&UUErhex3rtP>tyy{aEF>5CYTdeORToYXz|8xoVs~ szG3F8UvIZ|&G+{@RPFm{t3iFS=wlzgdbXrHd$gapGXov&?&RwP043&5vH$=8 delta 122 zcmZo)D|TSD*oGC{0+Iy`U;v^QD&;-dyo0-hQQ%YuL=;4?ShI?`*@m~>hL>@>4KLHX z_V(hbOhC-My?81M_wMa~0$7t>HMnP*F)#?&CN`qkri>@!b4{3Fn^M`Q0Y|4DLz O>KU%gKm*;Ke4PNdUMm3r diff --git a/src/Q.php b/src/Q.php index 244e8f4..dee6c7f 100644 --- a/src/Q.php +++ b/src/Q.php @@ -595,6 +595,9 @@ class Q_Socket /** Leave a room, optionally forwarding data to the room's leave handler */ function leave($room, $data = array()) { self::_cmd(array('cmd' => 'leave', 'socketId' => $this->id, 'room' => $room, 'data' => $data)); } + /** Disconnect this client */ + function disconnect() { self::_cmd(array('cmd' => 'disconnect', 'socketId' => $this->id)); } + /** * Call a method on the remote client. Blocks until the client responds. * The client must have registered a handler via qs.handle('methodName', fn). diff --git a/src/Q/WebSocket.php b/src/Q/WebSocket.php index 9100e93..c786447 100644 --- a/src/Q/WebSocket.php +++ b/src/Q/WebSocket.php @@ -874,6 +874,9 @@ class Q_WebSocket case 'ack': self::sendAck($cmd['socketId'], $cmd['ackId'], $cmd['data']); break; + case 'disconnect': + self::disconnect($cmd['socketId']); + break; case 'rpc': self::handleRpc($cmd); break;