使用php-mqtt库实现设备Ping功能时超时问题求助
php-mqtt库实现设备Ping功能时超时问题求助
我现在在做一个PHP网站向公共MQTT服务器发送"ping"请求,然后等待设备响应的功能。目前已经确认几个环节是正常的:
- ✅ PHP到MQTT Broker的消息发布正常
- ✅ 设备能成功订阅Broker的消息
- ✅ 设备能正常向Broker发送响应消息
但是明明设备在请求发出后2-3秒就把响应发到了正确的主题上,我的代码却总是触发超时。有没有大佬能帮忙看看问题出在哪?
以下是我的代码:
<?php require 'vendor/autoload.php'; use PhpMqtt\Client\MqttClient; use PhpMqtt\Client\ConnectionSettings; use PhpMqtt\Client\Message; $broker = 'test.mosquitto.org'; $port = 1883; $username = ''; $password = ''; $mainTopic = '!!!testlab'; $ackTimeout = 30; $testMessage = 'Broker Test'; $brokerStatus = sendText($broker, $port, $username, $password, $mainTopic, $testMessage, $ackTimeout); if ($brokerStatus === 0) { echo "Broker OK, RPi OK\n"; } elseif ($brokerStatus === 1) { die("Broker offline\n"); } else { die("Broker OK, RPi Timeout\n"); } function sendText($broker, $port, $username, $password, $mainTopic, $message, $ackTimeout) { try { $client = new MqttClient($broker, $port, 'php-client'); $settings = (new ConnectionSettings); if (!empty($username)) { $settings->setUsername($username); } if (!empty($password)) { $settings->setPassword($password); } $client->connect($settings); $messageId = uniqid(); $subTopic = $mainTopic . '/' . $messageId; $acknowledgmentTopic = $subTopic . '/ack'; $messageData = [ 'id' => $messageId, 'message' => $message, 'timestamp' => time(), ]; $messagePayload = json_encode($messageData); $acknowledgment = null; $startTime = microtime(true); $client->subscribe($acknowledgmentTopic, function (Message $message) use ($acknowledgmentTopic, &$acknowledgment) { $acknowledgmentData = json_decode($message->getPayload(), true); if ($acknowledgmentData && isset($acknowledgmentData['code'])) { $acknowledgmentCode = $acknowledgmentData['code']; $acknowledgmentMessage = isset($acknowledgmentData['message']) ? $acknowledgmentData['message'] : ''; if ($acknowledgmentCode == 0) { $acknowledgment = 0; } else { $acknowledgment = (int)$acknowledgmentCode; } } }); $client->registerLoopEventHandler(function (MqttClient $client) use ($acknowledgmentTopic, &$acknowledgment, $ackTimeout, $startTime) { if ($acknowledgment !== null) { $client->interrupt(); } $elapsedTime = microtime(true) - $startTime; if ($elapsedTime >= $ackTimeout) { $acknowledgment = 2; $client->interrupt(); } }); $client->publish($subTopic . '/text', $messagePayload); $client->loop(); $client->disconnect(); return $acknowledgment ?? 2; } catch (\Throwable $e) { if($debug){echo "Fehler: " . $e->getMessage() . "\n";} return 1; // Verbindungsfehler zum Broker } } ?>
备注:内容来源于stack exchange,提问作者DatabaseMan
相关产品推荐
相关产品推荐

