From b774ea35bd18c82164827f322f0d54fb5ef3fb2e Mon Sep 17 00:00:00 2001 From: Tim Fry Date: Sat, 25 Oct 2025 18:44:23 -0300 Subject: [PATCH] Add listeners to base_websocket_system_service --- .../classes/base_websocket_system_service.php | 51 +++++++++++++++--- .../resources/classes/websocket_message.php | 54 +++++++++---------- 2 files changed, 72 insertions(+), 33 deletions(-) diff --git a/core/websockets/resources/classes/base_websocket_system_service.php b/core/websockets/resources/classes/base_websocket_system_service.php index 27c65dc102..5c03529a9c 100644 --- a/core/websockets/resources/classes/base_websocket_system_service.php +++ b/core/websockets/resources/classes/base_websocket_system_service.php @@ -24,7 +24,20 @@ abstract class base_websocket_system_service extends service implements websocke private $timers; - //abstract protected function reload_settings(): void; + /** + * Array of topics and their callbacks + * @var array + */ + protected $topics; + + /** + * Array of listeners + * Listener is an array of socket and callback used to listen for events on the socket. When a listener is added, + * the socket is added to the array of listeners. When the socket is closed, the listener is removed from the + * array of listeners. When an event is received on the respective socket, the provided callback is called. + * @var array + */ + protected $listeners; protected static function display_version(): void { echo "System Dashboard Service 1.0\n"; @@ -69,10 +82,24 @@ abstract class base_websocket_system_service extends service implements websocke self::$websocket_host = $host; } + /** + * Add a socket listener + * + * @param $socket + * @param callable $callback + * @return void + */ + protected function add_listener($socket, callable $callback): void { + $this->listeners[] = [$socket, $callback]; + } + public function run(): int { // set the timers property as an array $this->timers = []; + // Set the listeners property as an array + $this->listeners = []; + // re-read the config file to get any possible changes parent::$config->read(); @@ -94,7 +121,9 @@ abstract class base_websocket_system_service extends service implements websocke $suppress_ws_message = false; while ($this->running) { - $read = []; + // Get the array of sockets to read from + $listeners = array_column($this->listeners, 0); + // reconnect to websocket server if ($this->ws_client === null || !$this->ws_client->is_connected()) { // reconnect failed @@ -105,7 +134,9 @@ abstract class base_websocket_system_service extends service implements websocke } if ($this->ws_client !== null && $this->ws_client->is_connected()) { - $read[] = $this->ws_client->socket(); + // Combine the websocket client and the listeners into a single array + $read = array_merge($listeners, $this->ws_client->socket()); + // Reset the suppress message flag $suppress_ws_message = false; } @@ -129,6 +160,14 @@ abstract class base_websocket_system_service extends service implements websocke $this->handle_websocket_event($this->ws_client); continue; } + // Other listeners + foreach ($this->listeners as $listener) { + if ($resource === $listener[0]) { + // Call the callback function provided by the add_listener function + call_user_func($listener[1]); + continue; + } + } } } } @@ -143,7 +182,7 @@ abstract class base_websocket_system_service extends service implements websocke $callable = $array['callable']; // Call the callback and see if it returns a value for the next timer $next_timer = call_user_func($callable); - if ($next_timer !== null && is_numeric($next_timer)) { + if (is_numeric($next_timer)) { // Set the timer again when requested by called function returning a value $this->set_timer($next_timer, $callable); } @@ -244,8 +283,8 @@ abstract class base_websocket_system_service extends service implements websocke /** * Allows the service to register a callback so when the topic arrives the callable is called - * @param type $topic - * @param type $callable + * @param string $topic + * @param callable $callable */ protected function on_topic($topic, $callable) { if (!isset($this->topics[$topic])) { diff --git a/core/websockets/resources/classes/websocket_message.php b/core/websockets/resources/classes/websocket_message.php index 48d0796306..0aa81dd654 100644 --- a/core/websockets/resources/classes/websocket_message.php +++ b/core/websockets/resources/classes/websocket_message.php @@ -308,19 +308,19 @@ class websocket_message extends base_message { /** * Helper function to respond with a connected message - * @param type $request_id - * @return type + * @param string|int $request_id + * @return string */ - public static function connected($request_id = '') { + public static function connected($request_id = ''): string { return static::request_authentication($request_id); } /** * Helper function to respond with a authentication message - * @param type $request_id - * @return type + * @param string|int $request_id + * @return string */ - public static function request_authentication($request_id = '') { + public static function request_authentication($request_id = ''): string { $class = static::class; return (new $class()) ->request_id($request_id) @@ -334,12 +334,12 @@ class websocket_message extends base_message { /** * Helper function to respond with a bad request message - * @param type $request_id - * @param type $service - * @param type $topic - * @return type + * @param string|int $request_id + * @param string $service + * @param string $topic + * @return string */ - public static function request_is_bad($request_id = '', $service = '', $topic = '') { + public static function request_is_bad($request_id = '', string $service = '', string $topic = ''): string { $class = static::class; return (new $class()) ->request_id($request_id) @@ -352,12 +352,12 @@ class websocket_message extends base_message { /** * Helper function to respond with an authenticated message - * @param type $request_id - * @param type $service - * @param type $topic - * @return type + * @param string|int $request_id + * @param string $service + * @param string $topic + * @return string */ - public static function request_authenticated($request_id = '', $service = '', $topic = 'authenticated') { + public static function request_authenticated($request_id = '', string $service = '', string $topic = 'authenticated'): string { $class = static::class; return (new $class()) ->request_id($request_id) @@ -371,12 +371,12 @@ class websocket_message extends base_message { /** * Helper function to respond with an unauthorized request message - * @param type $request_id - * @param type $service - * @param type $topic - * @return type + * @param string|int $request_id + * @param string $service + * @param string $topic + * @return string */ - public static function request_unauthorized($request_id = '', $service = '', $topic = 'unauthorized') { + public static function request_unauthorized($request_id = '', string $service = '', string $topic = 'unauthorized'): string { $class = static::class; return (new $class()) ->request_id($request_id) @@ -389,12 +389,12 @@ class websocket_message extends base_message { /** * Helper function to respond with a forbidden message - * @param type $request_id - * @param type $service - * @param type $topic - * @return type + * @param string|int $request_id + * @param string $service + * @param string $topic + * @return string */ - public static function request_forbidden($request_id = '', $service = '', $topic = 'forbidden') { + public static function request_forbidden($request_id = '', string $service = '', string $topic = 'forbidden'): string { $class = static::class; return (new $class()) ->request_id($request_id) @@ -411,7 +411,7 @@ class websocket_message extends base_message { * @return static|null Returns a new websocket_message object (or child object) * @throws \InvalidArgumentException */ - public static function create_from_json_message($websocket_message_json) { + public static function create_from_json_message($websocket_message_json): ?websocket_message { if (empty($websocket_message_json)) { // Nothing to do return null;