Subscribe stuck in loop
m-genser opened this issue · 2 comments
$mqtt->loop(true, true, 10);
don't exit the loop after 10 seconds like it's intended. It always exits by PHP max_execution_time
instead.
Tested with following code:
<?php
echo "[" . date("Y-m-d H:i:s") . "] Runtime started<br>" . PHP_EOL;
// Load MQTT client
require_once(__DIR__ . "/vendor/autoload.php");
// Define connection
$connectionSettings = (new \PhpMqtt\Client\ConnectionSettings)
->setUsername("marvin")
->setPassword("super#Secret")
->setConnectTimeout(3)
->setUseTls(true)
->setTlsSelfSignedAllowed(true);
$server = 'some-mqtt.broker.com';
$port = 8883;
$clientId = 'marvin';
$mqtt = new \PhpMqtt\Client\MqttClient($server, $port, $clientId);
$mqtt->connect($connectionSettings, true);
// Subscribe to MQTT-Topic
$mqtt->subscribe('some/data/#', function ($topic, $message) {
echo sprintf("Incoming message: [%s]: %s\n<br>", $topic, $message);
}, 0);
// Run loop max 10 seconds
$mqtt->loop(true, true, 10);
// Close connection
$mqtt->disconnect();
echo "[" . date("Y-m-d H:i:s") . "] Runtime closed<br>" . PHP_EOL;
I think you misread the description of the MqttClient::loop()
method:
client/src/Contracts/MqttClient.php
Lines 127 to 149 in c05f007
The This means there may be no open subscriptions [...] We do not exit after the given amount of time if there are open topic subscriptions though.
part is important. A subscription is normally not a short-term thing, but intended to be kept for quite a while.
What you are actually looking for is the example about interrupting the loop with a loop event handler. All you need to do is register a loop event handler, which checks for the elapsed time since starting the loop to determine whether it is time to exit already:
$client->registerLoopEventHandler(function (MqttClient $client, float $elapsedTime) {
if ($elapsedTime >= 10) {
$client->interrupt();
}
});
To shed some light on the 2nd and 3rd parameter of the loop()
method:
When publishing messages with QoS 1 or 2, the client needs confirmation from the broker that the message was received/delivered. If no such confirmation is received, the client will retry sending queued messages. To prevent the client from getting stuck in an infinite loop (if delivery of the message is impossible), these parameters can be used to forcefully cancel the retries after some time.
Yes, unfortunately I misunderstood. Thought that was a issue.
Thank you for the solution!