[Перевод] Использование протокола MQTT в PHP

phywcyanexlgd501qnwh5gmu81m.png


Статья посвящена использованию библиотеки 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, успешно настроив публикацию сообщений и их получение клиентом по подписке.

oug5kh6sjydt9llengsiebnp40w.png

© Habrahabr.ru