### Bash Example: Running Shared Subscription Subscribers and Publisher Source: https://github.com/ultraembeddedlab/php-iot/blob/main/docs/shared-subscriptions.md This bash script demonstrates how to run multiple shared subscription subscribers and a publisher for testing. It starts two subscriber instances in separate terminals and then publishes a message using a simple publisher script. This allows observation of message distribution across subscribers. ```bash # Terminal 1 - Start first subscriber php examples/shared_subscription_example.php # Terminal 2 - Start second subscriber php examples/shared_subscription_example.php # Terminal 3 - Publish messages php examples/simple_publish.php sensors/temperature "22.5" ``` -------------------------------- ### Running the Flow Control Example Source: https://github.com/ultraembeddedlab/php-iot/blob/main/docs/flow-control.md Instructions on how to execute a complete working example of MQTT 5.0 flow control in PHP. This involves running a specific PHP script from the command line. ```bash php examples/flow_control_example.php ``` -------------------------------- ### Install Project Dependencies with Composer Source: https://github.com/ultraembeddedlab/php-iot/blob/main/CONTRIBUTING.md This command installs the project's dependencies using Composer after cloning the repository. It requires PHP and Composer to be installed on the system. ```bash git clone https://github.com/UltraEmbeddedLab/php-iot.git cd php-iot composer install ``` -------------------------------- ### Execute Topic Alias Example Script (CLI) Source: https://github.com/ultraembeddedlab/php-iot/blob/main/docs/topic-aliases.md Runs a complete working example of MQTT 5.0 topic aliases using PHP. This command executes the example script located at `examples/topic_alias_example.php` in the project directory. ```bash php examples/topic_alias_example.php ``` -------------------------------- ### Install PHP IoT MQTT Client via Composer Source: https://github.com/ultraembeddedlab/php-iot/blob/main/README.md Installs the PHP IoT MQTT Client library using Composer. This is the standard method for adding the package to your PHP project. ```bash composer require ultraembeddedlab/php-iot ``` -------------------------------- ### Run Server Disconnect Example (Bash) Source: https://github.com/ultraembeddedlab/php-iot/blob/main/docs/server-disconnect.md This snippet shows how to execute the server disconnect example script using PHP from the command line. It's used to test the library's DISCONNECT packet handling by triggering a disconnect event. ```bash # Start the example php examples/server_disconnect_example.php # In another terminal, connect with same client ID to trigger 0x8E ``` -------------------------------- ### Configuring TLS Options for MQTT Client Source: https://github.com/ultraembeddedlab/php-iot/blob/main/README.md Provides an example of how to configure TLS options for secure MQTT connections. This includes verifying peer certificates and specifying certificate files. ```php $options = $options->withTls([ 'ssl' => [ 'verify_peer' => true, 'verify_peer_name' => true, 'cafile' => '/path/to/ca.crt', 'local_cert' => '/path/to/client.crt', 'local_pk' => '/path/to/client.key', ], ]); ``` -------------------------------- ### MQTT 5.0 Topic Alias Example Source: https://github.com/ultraembeddedlab/php-iot/blob/main/README.md Demonstrates the use of topic aliases in MQTT 5.0 to reduce bandwidth by using numeric identifiers for frequently used topics. ```php $client->publish('long/topic/name', 'data', new PublishOptions( properties: ['topic_alias' => 1], )); ``` -------------------------------- ### Run Tests with Composer Source: https://github.com/ultraembeddedlab/php-iot/blob/main/CONTRIBUTING.md These commands execute the project's test suite using Composer. The first command runs all tests, while the second runs tests with code coverage reporting enabled. Ensure Composer is installed. ```bash # Run tests composer test # Run tests with coverage composer test:coverage ``` -------------------------------- ### Perform Static Analysis with Composer Source: https://github.com/ultraembeddedlab/php-iot/blob/main/CONTRIBUTING.md This command runs PHPStan at its maximum level to perform static analysis on the codebase. It helps identify potential bugs and code quality issues. PHPStan and Composer must be installed. ```bash composer stan ``` -------------------------------- ### Accessing and Using Flow Control Manager Source: https://github.com/ultraembeddedlab/php-iot/blob/main/docs/flow-control.md Provides examples of how to access the `FlowControl` manager from an MQTT client and use its methods to check the current status of in-flight messages, maximum allowed messages, and packet pending status. ```php // Get the flow control manager from the client (after connect) $flow = $client->flowControl; // Check current status $inFlight = $flow->getInFlightCount(); // Current in-flight messages $max = $flow->getMaxInFlight(); // Maximum allowed $canSend = $flow->canSend(); // Is a slot available? // Get pending packet IDs $pending = $flow->getPendingPacketIds(); // Returns list // Check if specific packet is pending $isPending = $flow->isPending($packetId); // Returns bool // Get send timestamp for a packet $sendTime = $flow->getSendTime($packetId); // Returns float|null // Find timed-out packets $timedOut = $flow->getTimedOutPackets(30.0); // Packets pending > 30 seconds ``` -------------------------------- ### Check Type Coverage with Composer Source: https://github.com/ultraembeddedlab/php-iot/blob/main/CONTRIBUTING.md This command checks the type coverage of the project's code using Composer. It helps ensure that strict types are used effectively throughout the codebase. Composer must be installed. ```bash composer type-coverage ``` -------------------------------- ### Receive MQTT Messages with PHP Source: https://context7.com/ultraembeddedlab/php-iot/llms.txt Illustrates various methods for receiving messages from an MQTT broker using the PHP client. It covers callback-based handling using `onMessage()`, synchronous polling with `loopOnce()`, blocking await with `awaitMessage()`, and asynchronous iteration using the `messages()` generator. Examples show how to access message details like topic, payload, QoS, retain flag, and MQTT 5.0 properties. ```php connect(); $client->subscribe(['sensors/#'], qos: 1); // Option 1: Callback-based handling $client->onMessage(function (InboundMessage $message) { echo "Topic: {$message->topic}\n"; echo "Payload: {$message->payload}\n"; echo "QoS: {$message->qos->value}\n"; echo "Retain: " . ($message->retain ? 'yes' : 'no') . "\n"; // MQTT 5.0 properties if ($message->properties) { if (isset($message->properties['content_type'])) { echo "Content-Type: {$message->properties['content_type']}\n"; } if (isset($message->properties['message_expiry_interval'])) { echo "Expires in: {$message->properties['message_expiry_interval']}s\n"; } if (isset($message->properties['user_properties'])) { foreach ($message->properties['user_properties'] as $key => $value) { echo " {$key}: {$value}\n"; } } } }); // Run event loop with callback $client->run( onMessage: fn($msg) => null, // Handler already set via onMessage() idleSleep: 0.01, ); // Option 2: Manual polling with loopOnce while (true) { $client->loopOnce(0.1); // Process incoming packets, 100ms timeout } // Option 3: Await single message (blocking) $message = $client->awaitMessage(timeoutSec: 5.0); if ($message) { echo "Received: {$message->payload}\n"; } // Option 4: Generator-based iteration foreach ($client->messages(timeoutSec: 0.2) as $message) { echo "Message on {$message->topic}: {$message->payload}\n"; } $client->disconnect(); ``` -------------------------------- ### Implement Custom Redis Session Store (PHP) Source: https://github.com/ultraembeddedlab/php-iot/blob/main/docs/session-persistence.md This example provides a custom session store implementation using Redis by adhering to the `SessionStoreInterface`. It defines methods for saving, loading, deleting, and checking the existence of session data. ```php use ScienceStories\Mqtt\Contract\SessionStoreInterface; use ScienceStories\Mqtt\Session\SessionState; class RedisSessionStore implements SessionStoreInterface { // Assume $this->redis is an initialized Redis client instance public function save(string $clientId, SessionState $state): void { $this->redis->set("mqtt:session:{$clientId}", serialize($state)); } public function load(string $clientId): ?SessionState { $data = $this->redis->get("mqtt:session:{$clientId}"); return $data ? unserialize($data) : null; } public function delete(string $clientId): void { $this->redis->del("mqtt:session:{$clientId}"); } public function exists(string $clientId): bool { return $this->redis->exists("mqtt:session:{$clientId}"); } } ``` -------------------------------- ### Attach User Properties to Messages in PHP Source: https://github.com/ultraembeddedlab/php-iot/blob/main/README.md This example shows how to attach custom metadata, or user properties, to MQTT messages using the PHP IoT MQTT Client. The `PublishOptions` are used to define a `user_properties` array containing key-value pairs for custom metadata like 'source' and 'version'. ```php $client->publish('events/user', $payload, new PublishOptions( properties: [ 'user_properties' => [ 'source' => 'web-app', 'version' => '1.0', ], ] )); ``` -------------------------------- ### Modernize Code with Composer Source: https://github.com/ultraembeddedlab/php-iot/blob/main/CONTRIBUTING.md This Composer command executes Rector to automatically modernize the codebase. Rector analyzes the code and applies transformations to update it to newer PHP versions or coding standards. Ensure Composer is installed. ```bash composer rector ``` -------------------------------- ### Unsubscribe from MQTT Topics with PHP Source: https://context7.com/ultraembeddedlab/php-iot/llms.txt Shows how to unsubscribe from specific MQTT topics using the PHP client library. This action stops the client from receiving messages for the specified topic filters. The example demonstrates subscribing to multiple topics and then unsubscribing from a subset of them, leaving the remaining subscriptions active. ```php connect(); // Subscribe to multiple topics $client->subscribe(['sensors/#', 'alerts/#', 'status/#']); // ... process messages ... // Unsubscribe from specific topics $client->unsubscribe(['alerts/#', 'status/#']); // Only sensors/# subscription remains active $client->disconnect(); ``` -------------------------------- ### Full MQTT Client Subscription and Loop Source: https://github.com/ultraembeddedlab/php-iot/blob/main/README.md Demonstrates setting up a full MQTT client, connecting to a broker, subscribing to topics, and entering a loop to process incoming messages. This is for more advanced, long-running applications. ```php use ScienceStories\Mqtt\Client\Client; use ScienceStories\Mqtt\Client\Options; use ScienceStories\Mqtt\Protocol\MqttVersion; use ScienceStories\Mqtt\Transport\TcpTransport; $options = new Options( host: 'broker.example.com', port: 1883, version: MqttVersion::V5_0, ); $options = $options ->withClientId('my-client') ->withKeepAlive(60) ->withCleanSession(true); $client = new Client($options, new TcpTransport()); $client->connect(); // Subscribe to topics $client->subscribe([ ['filter' => 'sensors/#', 'qos' => 1], ]); // Handle incoming messages $client->onMessage(function ($message) { echo "Received: {$message->payload} on {$message->topic}\n"; }); // Listen for messages while (true) { $client->loopOnce(1.0); } ``` -------------------------------- ### Configure Full Client with Options Builder in PHP Source: https://context7.com/ultraembeddedlab/php-iot/llms.txt Demonstrates how to build a fully configured MQTT client using the Options builder. This includes setting connection details, authentication, TLS, auto-reconnect, and Last Will and Testament (LWT) options. It's suitable for production environments needing advanced control. ```php withClientId('device-gateway-001') ->withKeepAlive(60) ->withCleanSession(false) ->withUser('gateway', 'secure-password') ->withTls([ 'ssl' => [ 'verify_peer' => true, 'verify_peer_name' => true, 'cafile' => '/etc/ssl/certs/ca-certificates.crt', ], ]) ->withAutoReconnect( enable: true, maxAttempts: 10, baseDelay: 0.5, maxDelay: 30.0, jitter: 0.2, ) ->withSessionExpiry(86400) // 24 hours ->withTopicAliasMaximum(10) ->withReceiveMaximum(100) ->withWill(new WillOptions( topic: 'devices/gateway-001/status', payload: json_encode(['status' => 'offline', 'timestamp' => time()]), qos: QoS::AtLeastOnce, retain: true, )); // Create and connect client $client = new Client($options, new TcpTransport()); $result = $client->connect(); echo "Connected: " . ($result->reasonCode === 0 ? 'yes' : 'no') . "\n"; echo "Session Present: " . ($result->sessionPresent ? 'yes' : 'no') . "\n"; echo "Protocol: {$result->protocol} {$result->version}\n"; // Use the client... $client->disconnect(); ``` -------------------------------- ### Run Tests and Analysis with Composer Source: https://github.com/ultraembeddedlab/php-iot/blob/main/README.md This section provides common Composer commands for managing the PHP project's testing and code quality. It includes commands for running unit tests, generating code coverage reports, performing static analysis, and enforcing code style. ```bash # Run tests composer test # Run tests with coverage composer test:coverage # Static analysis composer stan # Code style composer pint ``` -------------------------------- ### Client Configuration with Options Builder Source: https://context7.com/ultraembeddedlab/php-iot/llms.txt Demonstrates how to configure the MQTT client using the `Options` builder for detailed control over connection parameters, including TLS, auto-reconnect, and MQTT 5.0 specific settings. ```APIDOC ## Client Configuration with Options Builder ### Description This section explains how to use the `Client` class with the `Options` builder to fully configure connection settings. This is recommended for production environments needing advanced features like auto-reconnect, TLS, and MQTT 5.0 support. ### Method N/A (Code Example) ### Endpoint N/A (Client Configuration) ### Parameters N/A (Configuration is done via object instantiation and method chaining) ### Request Example ```php withClientId('device-gateway-001') ->withKeepAlive(60) ->withCleanSession(false) ->withUser('gateway', 'secure-password') ->withTls([ 'ssl' => [ 'verify_peer' => true, 'verify_peer_name' => true, 'cafile' => '/etc/ssl/certs/ca-certificates.crt', ], ]) ->withAutoReconnect( enable: true, maxAttempts: 10, baseDelay: 0.5, maxDelay: 30.0, jitter: 0.2, ) ->withSessionExpiry(86400) // 24 hours ->withTopicAliasMaximum(10) ->withReceiveMaximum(100) ->withWill(new WillOptions( topic: 'devices/gateway-001/status', payload: json_encode(['status' => 'offline', 'timestamp' => time()]), qos: QoS::AtLeastOnce, retain: true, )); // Create and connect client $client = new Client($options, new TcpTransport()); $result = $client->connect(); echo "Connected: " . ($result->reasonCode === 0 ? 'yes' : 'no') . "\n"; echo "Session Present: " . ($result->sessionPresent ? 'yes' : 'no') . "\n"; echo "Protocol: {$result->protocol} {$result->version}\n"; // Use the client... $client->disconnect(); ``` ### Response #### Success Response (200) - **reasonCode** (int) - The connection result code. - **sessionPresent** (bool) - Indicates if the session was already present. - **protocol** (string) - The MQTT protocol name. - **version** (string) - The MQTT protocol version. #### Response Example ```json { "reasonCode": 0, "sessionPresent": false, "protocol": "MQTT", "version": "5.0" } ``` ``` -------------------------------- ### Publish Messages with QoS and Options in PHP Source: https://context7.com/ultraembeddedlab/php-iot/llms.txt Illustrates how to publish MQTT messages using the `publish()` method. It covers different Quality of Service (QoS) levels (0, 1, and 2) and demonstrates setting publish-specific options like retain flags and MQTT 5.0 properties. QoS 1 and 2 messages return a packet ID upon acknowledgment. ```php connect(); // QoS 0: Fire and forget (returns 0) $client->publish('events/log', 'Application started'); // QoS 1: At least once delivery (returns packet ID on PUBACK) $packetId = $client->publish( 'sensors/temperature', '{"value": 22.5, "unit": "celsius"}', new PublishOptions( qos: QoS::AtLeastOnce, properties: [ 'content_type' => 'application/json', 'payload_format_indicator' => 1, // UTF-8 text 'message_expiry_interval' => 3600, 'user_properties' => [ 'sensor_id' => 'temp-sensor-01', 'location' => 'warehouse-a', ], ], ) ); echo "Published with packet ID: {$packetId}\n"; // QoS 2: Exactly once delivery (returns packet ID on PUBCOMP) $packetId = $client->publish( 'commands/critical', 'shutdown-sequence-initiated', new PublishOptions( qos: QoS::ExactlyOnce, properties: [ 'response_topic' => 'commands/critical/response', 'correlation_data' => 'req-' . uniqid(), ], ) ); echo "QoS 2 message completed with packet ID: {$packetId}\n"; // Retained message (broker stores last message for new subscribers) $client->publish( 'devices/gateway/status', '{"online": true}', new PublishOptions( qos: QoS::AtLeastOnce, retain: true, ) ); $client->disconnect(); ``` -------------------------------- ### Subscribe to MQTT Topics with PHP Source: https://context7.com/ultraembeddedlab/php-iot/llms.txt Demonstrates how to subscribe to MQTT topics using the PHP client library. Covers simple subscriptions, subscriptions with specific Quality of Service (QoS) levels, advanced subscriptions with MQTT 5.0 options (including user properties and retain handling), and shared subscriptions for load balancing. Requires the client to be connected to an MQTT broker. ```php connect(); // Simple subscription with default QoS 0 $client->subscribe(['sensors/temperature', 'sensors/humidity']); // Subscription with specific QoS $client->subscribe(['alerts/#'], qos: 2); // Advanced subscription with MQTT 5.0 options $result = $client->subscribeWith( filters: [ ['filter' => 'sensors/+/temperature', 'qos' => 1], ['filter' => 'devices/#', 'qos' => 2], ], options: new SubscribeOptions( noLocal: true, // Don't receive own publications retainAsPublished: true, // Preserve original retain flag retainHandling: 1, // 0=send retained, 1=if new sub, 2=never properties: [ 'user_properties' => [ 'subscription_type' => 'monitoring', ], ], ) ); echo "Subscribed with packet ID: {$result->packetId}\n"; foreach ($result->results as $idx => $code) { $status = $code <= 2 ? "QoS {$code} granted" : "Failed (0x" . dechex($code) . ")"; echo " Topic {$idx}: {$status}\n"; } // Shared subscription (MQTT 5.0) - load balance across subscribers $client->subscribe(['$share/workers/jobs/#'], qos: 1); $client->disconnect(); ``` -------------------------------- ### Simple MQTT Publish (Fire and Forget) Source: https://github.com/ultraembeddedlab/php-iot/blob/main/README.md Demonstrates the simplest way to publish a message to an MQTT broker without requiring a persistent connection. This method is suitable for one-off messages. ```php use ScienceStories\Mqtt\Easy\Mqtt; Mqtt::publish( host: 'broker.example.com', topic: 'sensors/temperature', payload: '23.5', ); ``` -------------------------------- ### MQTT Publish with TLS and Authentication Source: https://github.com/ultraembeddedlab/php-iot/blob/main/README.md Shows how to publish a message to an MQTT broker using TLS encryption and basic authentication. This is useful for secure communication with protected brokers. ```php use ScienceStories\Mqtt\Easy\Mqtt; Mqtt::publish( host: 'broker.example.com', topic: 'sensors/temperature', payload: '23.5', tls: true, username: 'user', password: 'secret', ); ``` -------------------------------- ### Initialize FileSessionStore (PHP) Source: https://github.com/ultraembeddedlab/php-iot/blob/main/docs/session-persistence.md This code shows how to instantiate the `FileSessionStore` for saving session data to the filesystem. It can be configured with a directory path and an optional default expiry time in seconds. ```php use ScienceStories\Mqtt\Session\FileSessionStore; // Basic usage $store = new FileSessionStore('/var/mqtt/sessions'); // With automatic expiry $store = new FileSessionStore('/var/mqtt/sessions', defaultExpirySeconds: 3600); ``` -------------------------------- ### MQTT 5.0 Publish with QoS and Properties Source: https://github.com/ultraembeddedlab/php-iot/blob/main/README.md Illustrates publishing a message using MQTT 5.0 protocol features, including specifying the Quality of Service (QoS) and custom properties like message expiry. ```php use ScienceStories\Mqtt\Easy\Mqtt; use ScienceStories\Mqtt\Protocol\QoS; Mqtt::publish( host: 'broker.example.com', topic: 'sensors/temperature', payload: '23.5', version: 'v5', qos: QoS::AtLeastOnce, properties: [ 'message_expiry_interval' => 3600, 'content_type' => 'text/plain', ], ); ``` -------------------------------- ### Subscribing to Topics Source: https://context7.com/ultraembeddedlab/php-iot/llms.txt This section explains how to subscribe to MQTT topics using the `subscribe()` and `subscribeWith()` methods. It covers simple subscriptions, subscriptions with specific Quality of Service (QoS) levels, advanced MQTT 5.0 subscription options, and shared subscriptions. ```APIDOC ## POST /api/subscribe ### Description Subscribes to one or more MQTT topics. Supports wildcard characters and MQTT 5.0 subscription options. ### Method POST ### Endpoint /api/subscribe ### Parameters #### Request Body - **filters** (array) - Required - An array of topic filters to subscribe to. Each item can be a string (topic) or an object with `filter` and `qos` properties. - **qos** (integer) - Optional - The default Quality of Service level for subscriptions (0, 1, or 2). Defaults to 0. - **options** (object) - Optional - MQTT 5.0 subscription options, including `noLocal`, `retainAsPublished`, `retainHandling`, and `properties`. ### Request Example ```json { "filters": [ "sensors/temperature", "sensors/humidity" ], "qos": 0 } ``` ### Request Example (Advanced) ```json { "filters": [ {"filter": "sensors/+/temperature", "qos": 1}, {"filter": "devices/#", "qos": 2} ], "options": { "noLocal": true, "retainAsPublished": true, "retainHandling": 1, "properties": { "user_properties": { "subscription_type": "monitoring" } } } } ``` ### Response #### Success Response (200) - **packetId** (integer) - The packet identifier for the subscription request. - **results** (array) - An array indicating the granted QoS level for each subscribed topic filter, or an error code. #### Response Example ```json { "packetId": 123, "results": [ 0, 2 ] } ``` ``` -------------------------------- ### Configure Auto-Reconnect Behavior (PHP) Source: https://github.com/ultraembeddedlab/php-iot/blob/main/docs/server-disconnect.md Demonstrates how to configure the client's auto-reconnect settings using the `withAutoReconnect` method. This includes setting the maximum attempts, base delay, and maximum delay for reconnections. ```php $options = $options->withAutoReconnect( enable: true, maxAttempts: 5, baseDelay: 0.2, maxDelay: 5.0, ); ``` -------------------------------- ### Simple One-Shot Publish Source: https://context7.com/ultraembeddedlab/php-iot/llms.txt The `Mqtt::publish()` static method allows for a single, simple message to be sent to an MQTT broker. It automates the connection, publishing, and disconnection process, making it suitable for scenarios where immediate message delivery is needed without maintaining a persistent connection. ```APIDOC ## POST /mqtt/publish ### Description Sends a single message to an MQTT broker with automatic connection, publishing, and disconnection. ### Method POST ### Endpoint /mqtt/publish ### Parameters #### Query Parameters - **host** (string) - Required - The hostname or IP address of the MQTT broker. - **topic** (string) - Required - The MQTT topic to publish the message to. - **payload** (string) - Required - The message content to be published. - **version** (string) - Optional - The MQTT protocol version to use (e.g., 'v3.1.1', 'v5'). Defaults to 'v3.1.1'. - **tls** (boolean) - Optional - Whether to use TLS/SSL encryption for the connection. Defaults to false. - **username** (string) - Optional - The username for broker authentication. - **password** (string) - Optional - The password for broker authentication. - **qos** (integer) - Optional - The Quality of Service level (0, 1, or 2). Defaults to 0. - **retain** (boolean) - Optional - Whether the broker should retain the message. Defaults to false. - **properties** (object) - Optional - MQTT 5.0 specific properties (e.g., message_expiry_interval, content_type, user_properties). ### Request Example ```php 3600, 'content_type' => 'application/json', 'user_properties' => [ 'sensor_id' => 'temp-001', 'location' => 'warehouse-a', ], ] ); ?> ``` ### Response #### Success Response (200) Indicates the message was successfully sent to the broker. #### Response Example (No specific response body is detailed for this simple publish operation, success is implied by lack of error.) ``` -------------------------------- ### Long-Running MQTT Connection and Publishing Source: https://github.com/ultraembeddedlab/php-iot/blob/main/README.md Shows how to establish a long-running MQTT connection using `Mqtt::connect()` and then publish multiple messages. This is suitable for clients that need to send data periodically. ```php use ScienceStories\Mqtt\Easy\Mqtt; use ScienceStories\Mqtt\Client\PublishOptions; use ScienceStories\Mqtt\Protocol\QoS; $client = Mqtt::connect( host: 'broker.example.com', port: 1883, version: 'v5', ); // Publish multiple messages $client->publish('sensors/temp', '23.5', new PublishOptions(qos: QoS::AtLeastOnce)); $client->publish('sensors/humidity', '65', new PublishOptions(qos: QoS::AtLeastOnce)); $client->disconnect(); ``` -------------------------------- ### Implement Session Persistence with File Store (PHP) Source: https://context7.com/ultraembeddedlab/php-iot/llms.txt Saves client state like subscriptions and pending messages to disk to survive broker restarts. Requires `cleanSession: false` and a stable client ID. The `FileSessionStore` handles persistence and cleanup of expired sessions. ```php withClientId('persistent-device-001') // Stable ID required ->withCleanSession(false) // Use persistent session ->withSessionExpiry(86400) // MQTT 5.0: 24-hour session ->withSessionStore($sessionStore); $client = new Client($options, new TcpTransport()); $result = $client->connect(); if ($result->sessionPresent) { echo "Resumed existing session - subscriptions restored\n"; } else { echo "New session - subscribing to topics\n"; $client->subscribe(['sensors/#', 'commands/#'], qos: 1); } // Process messages... foreach ($client->messages(0.5) as $message) { echo "Received: {$message->topic}\n"; } // Session state saved automatically on disconnect $client->disconnect(); // Cleanup expired sessions periodically $removed = $sessionStore->cleanupExpired(); echo "Cleaned up {$removed} expired sessions\n"; ``` -------------------------------- ### Publishing with Topic Aliases (PHP) Source: https://github.com/ultraembeddedlab/php-iot/blob/main/docs/topic-aliases.md Demonstrates how to publish messages using topic aliases. The first publish includes the full topic string and establishes an alias. Subsequent publishes to the same topic reuse the assigned alias, sending only the alias number and an empty topic string, thus saving bandwidth. ```php // First publish - establishes alias $client->publish('sensors/device1/temperature', '22.5'); // Packet contains: topic="sensors/device1/temperature", topic_alias=1 // Second publish - reuses alias $client->publish('sensors/device1/temperature', '23.0'); // Packet contains: topic="", topic_alias=1 (topic omitted) ``` -------------------------------- ### Publish MQTT Messages with Different QoS Levels in PHP Source: https://context7.com/ultraembeddedlab/php-iot/llms.txt This code snippet illustrates how to publish MQTT messages using different Quality of Service (QoS) levels in PHP. It covers QoS 0 (At Most Once), QoS 1 (At Least Once), and QoS 2 (Exactly Once), explaining their delivery guarantees and use cases. ```php connect(); // QoS 0: At Most Once (Fire and Forget) // - No acknowledgment, message may be lost // - Fastest, lowest overhead // - Use for: telemetry, non-critical data $client->publish('telemetry/heartbeat', time(), new PublishOptions(qos: QoS::AtMostOnce)); // QoS 1: At Least Once // - PUBACK acknowledgment ensures delivery // - Message may be duplicated if PUBACK lost // - Use for: sensor data, logs, events $packetId = $client->publish('sensors/temp', '22.5', new PublishOptions(qos: QoS::AtLeastOnce)); echo "QoS 1 acknowledged with packet ID: {$packetId}\n"; // QoS 2: Exactly Once // - 4-step handshake (PUBLISH → PUBREC → PUBREL → PUBCOMP) // - Guarantees no duplicates and no loss // - Use for: financial transactions, commands, critical events $packetId = $client->publish('commands/shutdown', 'graceful', new PublishOptions(qos: QoS::ExactlyOnce)); echo "QoS 2 completed with packet ID: {$packetId}\n"; $client->disconnect(); ``` -------------------------------- ### Publishing with QoS 1/2 and Flow Control Source: https://github.com/ultraembeddedlab/php-iot/blob/main/docs/flow-control.md Demonstrates publishing a message with QoS 1. The `FlowControl` manager automatically tracks in-flight messages. If the client is at capacity, the `publish()` method will wait for acknowledgments before sending new messages. ```php // FlowControl automatically tracks in-flight messages $packetId = $client->publish('topic', 'payload', new PublishOptions( qos: QoS::AtLeastOnce // QoS 1 )); // If at capacity, publish() will wait for ACKs before sending ``` -------------------------------- ### Publish Single MQTT Message (PHP) Source: https://context7.com/ultraembeddedlab/php-iot/llms.txt The Mqtt::publish() static method offers a simple way to send a single MQTT message. It automatically handles connection, publishing, and disconnection, making it suitable for fire-and-forget scenarios. Supports basic publishing, TLS/authentication, and advanced MQTT 5.0 features like QoS and custom properties. ```php 23.5, 'unit' => 'celsius']), version: 'v5', qos: QoS::AtLeastOnce, retain: true, properties: [ 'message_expiry_interval' => 3600, 'content_type' => 'application/json', 'user_properties' => [ 'sensor_id' => 'temp-001', 'location' => 'warehouse-a', ], ], ); ``` -------------------------------- ### Handle Server Shutting Down (MQTT 5.0, PHP) Source: https://github.com/ultraembeddedlab/php-iot/blob/main/docs/server-disconnect.md Shows how to react to the 'Server Shutting Down' MQTT 5.0 disconnect reason code (0x8B). It checks for an alternative server reference and falls back to retrying with exponential backoff if none is provided. ```php if ($disconnect->reasonCode === 0x8B) { // Check for alternative server if ($ref = $disconnect->getServerReference()) { // Connect to alternative server } else { // Retry with exponential backoff } } ``` -------------------------------- ### Check and Fix Code Style with Composer Source: https://github.com/ultraembeddedlab/php-iot/blob/main/CONTRIBUTING.md These Composer commands utilize Laravel Pint to manage code formatting. The first command checks the code style without making changes, while the second command automatically fixes any style issues. ```bash # Check code style composer pint -- --test # Fix code style composer pint ``` -------------------------------- ### Publishing Messages Source: https://context7.com/ultraembeddedlab/php-iot/llms.txt Details on how to use the `publish()` method to send messages to MQTT topics. Covers different QoS levels, retain flags, and MQTT 5.0 properties for message delivery control. ```APIDOC ## Publishing Messages ### Description The `publish()` method is used to send messages to specified topics. It supports various Quality of Service (QoS) levels, retain flags, and MQTT 5.0 properties for advanced message handling. QoS 1 and 2 messages provide acknowledgments. ### Method `publish(string $topic, string $payload, ?PublishOptions $options = null): int` ### Endpoint N/A (Method Call) ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body - **topic** (string) - The topic to publish the message to. - **payload** (string) - The message content. - **options** (PublishOptions|null) - Optional configuration for the publish operation. - **qos** (QoS) - Quality of Service level (0, 1, or 2). - **retain** (bool) - If true, the broker retains the message. - **properties** (array) - MQTT 5.0 properties (e.g., `content_type`, `user_properties`). ### Request Example ```php connect(); // QoS 0: Fire and forget (returns 0) $client->publish('events/log', 'Application started'); // QoS 1: At least once delivery (returns packet ID on PUBACK) $packetId = $client->publish( 'sensors/temperature', '{"value": 22.5, "unit": "celsius"}', new PublishOptions( qos: QoS::AtLeastOnce, properties: [ 'content_type' => 'application/json', 'payload_format_indicator' => 1, // UTF-8 text 'message_expiry_interval' => 3600, 'user_properties' => [ 'sensor_id' => 'temp-sensor-01', 'location' => 'warehouse-a', ], ], ) ); echo "Published with packet ID: {$packetId}\n"; // QoS 2: Exactly once delivery (returns packet ID on PUBCOMP) $packetId = $client->publish( 'commands/critical', 'shutdown-sequence-initiated', new PublishOptions( qos: QoS::ExactlyOnce, properties: [ 'response_topic' => 'commands/critical/response', 'correlation_data' => 'req-' . uniqid(), ], ) ); echo "QoS 2 message completed with packet ID: {$packetId}\n"; // Retained message (broker stores last message for new subscribers) $client->publish( 'devices/gateway/status', '{"online": true}', new PublishOptions( qos: QoS::AtLeastOnce, retain: true, ) ); $client->disconnect(); ``` ### Response #### Success Response (200) - **packetId** (int) - For QoS 1 and 2, returns the packet identifier upon successful acknowledgment (PUBACK or PUBCOMP). For QoS 0, returns 0. #### Response Example ```json { "packetId": 12345 } ``` ``` -------------------------------- ### Handle MQTT Events with PSR-14 in PHP Source: https://context7.com/ultraembeddedlab/php-iot/llms.txt This snippet demonstrates how to integrate with PSR-14 compatible event dispatchers to handle MQTT events such as message reception, packet transmission/reception, and server disconnects. It shows setting up a simple event dispatcher and attaching listeners for different event types. ```php listeners[$event][] = $listener; } public function dispatch(object $event): object { $class = get_class($event); foreach ($this->listeners[$class] ?? [] as $listener) { $listener($event); } return $event; } } $dispatcher = new SimpleEventDispatcher(); // Log all received messages $dispatcher->addListener(MessageReceived::class, function (MessageReceived $event) { echo "[MESSAGE] {$event->message->topic}: {$event->message->payload}\n"; }); // Monitor packet traffic $dispatcher->addListener(PacketSent::class, function (PacketSent $event) { echo "[TX] Packet type {$event->packetType}, {$event->bytes} bytes\n"; }); $dispatcher->addListener(PacketReceived::class, function (PacketReceived $event) { echo "[RX] Packet type {$event->packetType}, {$event->remainingLength} bytes\n"; }); // Handle server disconnects $dispatcher->addListener(ServerDisconnect::class, function (ServerDisconnect $event) { echo "[DISCONNECT] Code: {$event->disconnect->reasonCode}\n"; echo "Reason: {$event->disconnect->getReasonDescription()}\\n"; echo "Will reconnect: " . ($event->willReconnect ? 'yes' : 'no') . "\n"; }); $options = new Options(host: 'broker.example.com'); $client = new Client($options, new TcpTransport(), events: $dispatcher); $client->connect(); $client->subscribe(['test/#']); $client->publish('test/hello', 'world'); while (true) { $client->loopOnce(1.0); } ``` -------------------------------- ### Maintain Long-Running MQTT Client Connection (PHP) Source: https://context7.com/ultraembeddedlab/php-iot/llms.txt The Mqtt::connect() method establishes a reusable client instance for sessions requiring multiple operations, such as publishing multiple messages or subscribing to topics. This is ideal for maintaining a persistent connection with the MQTT broker. The client instance supports efficient multi-message publishing and a clean disconnect. ```php publish('sensors/temp', '22.5', new PublishOptions(qos: QoS::AtLeastOnce)); $client->publish('sensors/humidity', '65', new PublishOptions(qos: QoS::AtLeastOnce)); $client->publish('sensors/pressure', '1013.25', new PublishOptions( qos: QoS::ExactlyOnce, retain: true, properties: [ 'content_type' => 'text/plain', 'message_expiry_interval' => 7200, ], )); // Clean disconnect $client->disconnect(); ``` -------------------------------- ### Create and Query SessionState Object (PHP) Source: https://github.com/ultraembeddedlab/php-iot/blob/main/docs/session-persistence.md This code illustrates how to manually create a `SessionState` object and interact with its methods to query subscription status, pending QoS 2 messages, and session age. It also shows serialization and deserialization to/from arrays. ```php use ScienceStories\Mqtt\Session\SessionState; // Create state manually $state = new SessionState( subscriptions: ['sensors/#' => ['qos' => 1, 'options' => null]], pendingQos2: [1234], savedAt: time(), ); // Query state $state->hasSubscriptions(); // bool $state->hasPendingQos2(); // bool $state->getSubscriptionCount(); // int $state->getAge(); // int (seconds) $state->isExpired(3600); // bool (check against expiry) // Serialize/deserialize $array = $state->toArray(); $state = SessionState::fromArray($array); ```