在使用 simps/mqtt
连接阿里云物联网平台时,报错“async-io must be used in PHP CLI mode”通常是因为 simps/mqtt
的异步 I/O 功能只能在 PHP CLI 模式下运行,而不能在 Web 模式下运行。
simps/mqtt
使用了 react/event-loop
和 react/socket
等库来实现异步 I/O 操作。这些库依赖于 PHP 的事件循环,而事件循环通常只能在 CLI 模式下运行,因为在 Web 模式下,PHP 脚本是同步执行的,无法实现异步 I/O。
如果你需要在 ThinkPHP6 中使用 simps/mqtt
,建议将 MQTT 客户端放在 CLI 模式下运行。你可以创建一个命令行任务来处理 MQTT 的连接和消息处理。
步骤:
1. 在 ThinkPHP6 中创建一个命令行任务。
2. 在命令行任务中初始化 simps/mqtt
客户端并连接到阿里云物联网平台。
示例代码:
namespace app\command;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use Simps\MQTT\Client;
class MqttClient extends Command
{
protected function configure()
{
$this->setName('mqtt:client')->setDescription('MQTT Client');
}
protected function execute(Input $input, Output $output)
{
$client = new Client([
'host' => 'your-iot-endpoint',
'port' => 1883,
'username' => 'your-device-name',
'password' => 'your-device-secret',
'client_id' => 'your-client-id',
]);
$client->onConnect(function () use ($client) {
echo "Connected\n";
$client->subscribe('your-topic');
});
$client->onMessage(function ($topic, $message) {
echo "Received message on topic {$topic}: {$message}\n";
});
$client->loop();
}
}
然后在命令行中运行:
php think mqtt:client
如果你必须在 Web 模式下使用 MQTT,可以考虑使用同步的 MQTT 客户端库,而不是 simps/mqtt
。例如,可以使用 php-mqtt/client
这个库,它支持同步操作。
示例代码:
use PhpMqtt\Client\MqttClient;
use PhpMqtt\Client\ConnectionSettings;
$server = 'your-iot-endpoint';
$port = 1883;
$clientId = 'your-client-id';
$username = 'your-device-name';
$password = 'your-device-secret';
$mqtt = new MqttClient($server, $port, $clientId);
$connectionSettings = (new ConnectionSettings)
->setUsername($username)
->setPassword($password);
$mqtt->connect($connectionSettings, true);
$mqtt->subscribe('your-topic', function ($topic, $message) {
echo "Received message on topic {$topic}: {$message}\n";
});
$mqtt->loop(true);
如果你无法在 CLI 模式下运行 MQTT 客户端,可以考虑使用 WebSocket 或其他协议与阿里云物联网平台通信。阿里云物联网平台支持多种协议,你可以选择适合你场景的协议。
simps/mqtt
,建议在 CLI 模式下运行。