Comments (8)
Since $lastPayloadTime
is initially not set, the if
in the loop event handler is potentially an issue. Try to invert the call:
if (Carbon::now()->diffInSeconds($lastPayloadTime) > $timeout) { ... }
Also make sure $timeout
is defined (above code does not contain it).
Maybe it is enough to use $elapsedTime
passed to the loop event handler though? It contains the fractional seconds since the loop was started.
from laravel-client.
Thank you for the reply.
Here is my updated code:
$topic = 'topic';
$timeout = 5;
try{
$mqtt = MQTT::connection();
$mqtt->subscribe($topic, function (string $topic, string $message) use (&$lastPayloadTime, $mqtt){
$lastPayloadTime = Carbon::now();
echo $lastPayloadTime . "\n";
echo sprintf('Received QoS level 1 message on topic [%s]: %s', $topic, $message) . "\n";
// $mqtt->interrupt();
}, 0);
$mqtt->registerLoopEventHandler(function (MqttClient $client, float $elapsedTime) use (&$lastPayloadTime, $mqtt, $timeout) {
if ($elapsedTime > $timeout) {
echo "Payload not received within $elapsedTime seconds.\n";
$client->interrupt();
}
});
$mqtt->loop();
$mqtt->disconnect();
}catch (MqttClientException $e) {
echo $e;
}
I have tried using the $elapsedTime
to detect if message is not received after 5 seconds but it does not work. And I also have tried using $lastPayloadTime
and set it initially but it also does not work. It seems like the loop is not exited if the payload is not receive, the loop will only be exited if the MQQT broker is close. Is there a way to detect if the message is not received after specified duration?
Btw, I comment the $mqtt->interrupt()
because it will exit the process after receiving one message. It
from laravel-client.
This code works perfectly fine for me and interrupts after 5 seconds as expected. What is your operating system, PHP version and version of php-mqtt/client
as well as php-mqtt/laravel-client
(according to composer show
)?
However, you can cleanup the code a bit. You don't need all of the references:
$topic = 'topic';
$timeout = 5;
try{
$mqtt = MQTT::connection();
$mqtt->subscribe($topic, function (string $topic, string $message) use ($mqtt) {
echo sprintf('Received QoS level 0 message on topic [%s]: %s', $topic, $message) . PHP_EOL;
$mqtt->interrupt();
}, 0);
$mqtt->registerLoopEventHandler(function (MqttClient $client, float $elapsedTime) use ($timeout) {
if ($elapsedTime < $timeout) {
return;
}
echo sprintf('Payload not received within %s seconds.', $elapsedTime) . PHP_EOL;
$client->interrupt();
});
$mqtt->loop(true);
$mqtt->disconnect();
} catch (MqttClientException $e) {
echo $e->getMessage();
}
from laravel-client.
The code also works fine for me. However, after receiving one message, it exit the loop. I want to receive the messages continuously and if the message is not received for more than 5 seconds, it will exit the loop and give alert. And if it receive the messages back, it will enter the loop again. That is why on my previous code, I commented the $mqtt->interrupt()
because I want to continuously receive the messages.
My MQTT Broker will publish message every 0.5 seconds and I will receive the message every 0.5 seconds as well.
My OS is Windows 10, PHP version is 8.2.4, php-mqtt/laravel-client is 1.2. I do not have php-mqtt/client, is it required?
from laravel-client.
Oh ok, then I misunderstood your request. In this case the $elapsedTime
will not suffice and you do in fact need an additional variable to hold the time of the last retrieved messages:
$topic = 'topic';
$timeout = 5;
$lastMessageReceivedAt = null;
try{
$mqtt = MQTT::connection();
$mqtt->subscribe($topic, function (string $topic, string $message) use ($mqtt, &$lastMessageReceivedAt) {
$lastMessageReceivedAt = microtime(true);
echo sprintf('Received QoS level 0 message on topic [%s]: %s', $topic, $message) . PHP_EOL;
}, 0);
$mqtt->registerLoopEventHandler(function (MqttClient $client, float $elapsedTime) use ($timeout, &$lastMessageReceivedAt) {
if ($lastMessageReceivedAt === null || $lastMessageReceivedAt + $timeout > microtime(true)) {
return;
}
echo sprintf('Payload not received within %s seconds.', $elapsedTime) . PHP_EOL;
$client->interrupt();
});
$mqtt->loop(true);
$mqtt->disconnect();
} catch (MqttClientException $e) {
echo $e->getMessage();
}
from laravel-client.
The code works perfectly fine, thank you so much.
Whenever the payload is not received after 5 seconds, it will exit the process and I have to run the command again to receive payloads. I want to ask if there is a way to prevent the process from being exited and the command keeps running to receive payloads and give alert when the payload is not received after 5 seconds and also give alert when payload is received again.
Thank you.
from laravel-client.
That's rather simple to implement as well. You'll need some kind of state, I called it $alertFiring
. Since I assume that this alerting should also work before the first message was received, $lastMessageReceivedAt
needs to be initialized compared to the previous script.
I've also moved the alerting logic to a message received event handler to keep it separate from the subscription. This makes it a bit easier to understand, but it means that the alerting is applied to all subscriptions in total. If this is not desired, you can move the logic to your subscription callback as well.
$topic = 'topic';
$timeout = 5;
$lastMessageReceivedAt = microtime(true);
$alertFiring = false;
try{
$mqtt = MQTT::connection();
$mqtt->subscribe($topic, function (string $topic, string $message) use ($mqtt) {
echo sprintf('Received QoS level 0 message on topic [%s]: %s', $topic, $message) . PHP_EOL;
}, 0);
$mqtt->registerLoopEventHandler(function () use ($timeout, &$lastMessageReceivedAt, &$alertFiring) {
if ($alertFiring || $lastMessageReceivedAt + $timeout > microtime(true)) {
return;
}
echo sprintf('Payload not received within %s seconds.', $timeout) . PHP_EOL;
$alertFiring = true;
});
$mqtt->registerMessageReceivedEventHandler(function () use (&$lastMessageReceivedAt, &$alertFiring) {
$lastMessageReceivedAt = microtime(true);
if ($alertFiring) {
echo sprintf('Started to receive some data again.');
$alertFiring = false;
}
});
$mqtt->loop(true);
$mqtt->disconnect();
} catch (MqttClientException $e) {
echo $e->getMessage();
}
from laravel-client.
It works perfectly, thank you so much :)
from laravel-client.
Related Issues (20)
- could be use/configured as broadcast driver? HOT 3
- Godaddy Server(Shared Hosting) connecting to AWS iot core showing error. HOT 1
- Which Version of Laravel does it support? HOT 1
- Can this be used to make a MQTT sink? HOT 1
- Does it support auto reconnect? HOT 1
- Websocket port HOT 3
- Can the client publish messages on two different ports (TCP and WebSockets)? HOT 1
- Publish message as a bytes array HOT 8
- Support for Laravel 10 HOT 2
- SSL/TLS connection configuration HOT 6
- Is it possible to do subscribing to mutliple topics on 1 command? HOT 1
- How do you reset the command under supervisor when something changes in controller? HOT 3
- The broker did not acknowledge the connection attempt within the configured connection timeout period HOT 4
- plans to support php-mqtt client v2.0? HOT 2
- Cannot dispatch job inside subscribe closure HOT 1
- Certificate file on different disk HOT 1
- Settings without useBlockingSocket option HOT 1
- Enhancement Proposal: Addition of interrupt and subscribe methods to MQTT Facade and ConnectionManager Class HOT 2
- Unsubscribe HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from laravel-client.