[Перевод] Использование протокола MQTT в PHP
Статья посвящена использованию библиотеки php-mqtt/client в PHP-проектах для реализации функций подключения, подписки, отписки, а также обмена сообщениями между MQTT-клиентом и сервером.
Выбор клиентской библиотеки MQTT
Для этого проекта я выбрал php-mqtt/client, которая имеет больше всего загрузок через Composer. С другими клиентскими библиотеками PHP-MQTT можно ознакомиться на ресурсе Packagist через поиск по запросу MQTT.
Протокол MQTT используется в сценариях, требующих передачи очень малых объемов данных, в частности, для IoT-решений. Ввиду ограниченности возможностей PHP для сетевой коммуникации уместно использовать расширения вроде Swoole или Workerman, но в данной статье они рассматриваться не будут. Если интересно, вот пара актуальных вариантов:
- workerman/mqtt: асинхронный MQTT-клиент для PHP на базе workerman;
- simps/mqtt: анализ протокола MQTT и Coroutine-клиент для PHP.
Инициализация проекта
▍ Проверка версии PHP
В этом проекте для разработки и тестирования используется версия 7.4.21. Свою версию вы можете проверить следующей командой:
php --version
PHP 7.4.21 (cli) (built: Jul 12 2021 11:52:30) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
with Zend OPcache v7.4.21, Copyright (c), by Zend Technologies
▍ Установка php-mqtt/client через Composer
Composer — это менеджер управления зависимостями для PHP. Для установки с его помощью библиотеки выполните:
composer require php-mqtt/client
Подключение к MQTT-серверу
Мы будем использовать публичный MQTT-сервер EMQX. Вот данные для подключения:
- Broker: broker.emqx.io
- TCP Port: 1883
- SSL/TLS Port: 8883
▍Импорт файла автозагрузки и php-mqtt/client
require('vendor/autoload.php');
use \PhpMqtt\Client\MqttClient;
▍ Установка подключения к MQTT-брокеру
Устанавливаем адрес подключения, порт и топик. В то же время вызываем функцию rand
для генерации случайного ID клиента.
$server = 'broker.emqx.io';
$port = 1883;
$clientId = rand(5, 15);
$username = 'emqx_user';
$password = null;
$clean_session = false;
▍ Написание функции подключения
Используем приведенные выше параметры для подключения, устанавливая их через ConnectionSettings
:
$connectionSettings = new ConnectionSettings();
$connectionSettings
->setUsername($username)
->setPassword(null)
->setKeepAliveInterval(60)
->setLastWillTopic('emqx/test/last-will')
->setLastWillMessage('client disconnect')
->setLastWillQualityOfService(1);
Подписка
Подписываемся на топик emqx/test
и настраиваем функцию обратного вызова на обработку получаемого сообщения:
$mqtt->subscribe('emqx/test', function ($topic, $message) {
printf("Received message on topic [%s]: %s\n", $topic, $message);
}, 0);
Публикация
Создаем полезную нагрузку и вызываем функцию publish
для публикации сообщений в топике emqx/test
. После публикации клиенту нужно войти в режим опроса для обработки входящих сообщений и очереди повторной передачи:
for ($i = 0; $i< 10; $i++) {
$payload = array(
'protocol' => 'tcp',
'date' => date('Y-m-d H:i:s'),
'url' => 'https://github.com/emqx/MQTT-Client-Examples'
);
$mqtt->publish(
// топик
'emqx/test',
// полезная нагрузка
json_encode($payload),
// qos
0,
// удержание сообщений
true
);
printf("msg $i send\n");
sleep(1);
}
// Цикл для обработки входящих сообщений и очереди повторной передачи
$mqtt->loop(true);
Весь код
Код для подключения к серверу, публикации сообщений и их получения:
setUsername($username)
->setPassword(null)
->setKeepAliveInterval(60)
->setLastWillTopic('emqx/test/last-will')
->setLastWillMessage('client disconnect')
->setLastWillQualityOfService(1);
$mqtt = new MqttClient($server, $port, $clientId);
$mqtt->connect($connectionSettings, $clean_session);
printf("client connected\n");
$mqtt->subscribe('emqx/test', function ($topic, $message) {
printf("Received message on topic [%s]: %s\n", $topic, $message);
}, 0);
for ($i = 0; $i< 10; $i++) {
$payload = array(
'protocol' => 'tcp',
'date' => date('Y-m-d H:i:s'),
'url' => 'https://github.com/emqx/MQTT-Client-Examples'
);
$mqtt->publish(
// топик
'emqx/test',
// полезная нагрузка
json_encode($payload),
// qos
0,
// удержание сообщения
true
);
printf("msg $i send\n");
sleep(1);
}
$mqtt->loop(true);
Тестирование
Выполнив этот код, мы увидим, что клиент успешно подключается, а сообщения поочередно публикуются и получаются:
php pubsub_tcp.php
Заключение
В этом коротком проекте мы реализовали подключение к публичному MQTT-серверу с помощью php-mqtt/client, успешно настроив публикацию сообщений и их получение клиентом по подписке.