
Статья посвящена использованию библиотеки 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);Весь код
Код для подключения к серверу, публикации сообщений и их получения:
<?php
require('vendor/autoload.php');
use \PhpMqtt\Client\MqttClient;
use \PhpMqtt\Client\ConnectionSettings;
$server   = 'broker.emqx.io';
$port     = 1883;
$clientId = rand(5, 15);
$username = 'emqx_user';
$password = null;
$clean_session = false;
$connectionSettings  = new ConnectionSettings();
$connectionSettings
  ->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, успешно настроив публикацию сообщений и их получение клиентом по подписке.
 
 
          