PHP 是一種被廣泛應用的開放源代碼的多用途腳本語言,它可嵌入到 HTML 中,尤其適合 Web 開發。
本文主要介紹如何在 PHP 項目中使用 php-mqtt/client
客戶端庫 ,實現 MQTT 客戶端與 MQTT 服務器的連接、訂閱、取消訂閱、收發消息等功能。
MQTT 客戶端庫選擇
本文選擇了 composer 上下載量最高的 php-mqtt/client
這個客戶端庫,更多 PHP-MQTT 客戶端庫可以在 Packagist - Search MQTT 中查看。
有關 php-mqtt/client 更多使用文檔請參閱 Packagist php-mqtt/client。
MQTT 通信屬於 HTTP 體系之外的網絡通信場景,由於 PHP 特性限制,使用 PHP 體系中的 Swoole/Workerman 等專為網絡通信打造的拓展可以帶來更好的體驗,其使用本文不再贅述,相關的 MQTT 客戶端庫如下:
- workerman/mqtt:Asynchronous MQTT client for PHP based on workerman.
- simps/mqtt:MQTT Protocol Analysis and Coroutine Client for PHP.
項目初始化
確認 PHP 版本
本項目使用 7.4.21 進行開發測試,讀者可用如下命令確認 PHP 的版本。
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
使用 Composer 安裝 php-mqtt/client 客戶端
Composer 是 PHP 的一個依賴管理工具,它能管理你的 PHP 項目所需要的所有依賴關系。
composer require php-mqtt/client
PHP MQTT 使用
連接 MQTT 服務器
本文將使用 EMQ X 提供的 免費公共 MQTT 服務器,該服務基於 EMQ X 的 MQTT 物聯網雲平台 創建。服務器接入信息如下:
- Broker: broker-cn.emqx.io
- TCP Port: 1883
- SSL/TLS Port: 8883
導入 composer autoload 文件和 php-mqtt/client
require('vendor/autoload.php');
use \PhpMqtt\Client\MqttClient;
設置 MQTT Broker 連接參數
設置 MQTT Broker 連接地址,端口以及 topic,同時我們調用 PHP rand
函數隨機生成 MQTT 客戶端 id。
$server = 'broker-cn.emqx.io';
$port = 1883;
$clientId = rand(5, 15);
$username = 'emqx_user';
$password = null;
$clean_session = false;
編寫 MQTT 連接函數
使用上述的參數進行連接,通過 ConnectionSettings
設置連接參數,比如
$connectionSettings = new ConnectionSettings();
$connectionSettings
->setUsername($username)
->setPassword(null)
->setKeepAliveInterval(60)
// Last Will 設置
->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);
發布消息
構造一個 payload,調用 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(
// topic
'emqx/test',
// payload
json_encode($payload),
// qos
0,
// retain
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)
// Last Will 設置
->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(
// topic
'emqx/test',
// payload
json_encode($payload),
// qos
0,
// retain
true
);
printf("msg $i send\n");
sleep(1);
}
$mqtt->loop(true);
測試
運行 MQTT 消息發布代碼,我們將看到客戶端已經成功連接,且消息已經逐條發布並接收成功:
php pubsub_tcp.php
總結
至此,我們完成了使用 php-mqtt/client 客戶端連接到公共 MQTT 服務器,並實現了測試客戶端與 MQTT 服務器的連接、消息發布和訂閱。
版權聲明: 本文為 EMQ 原創,轉載請注明出處。