You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.20 13:09:30