php作为mqtt客户端,关于php:simpsmqtt适用于-PHP-的-MQTT-协议解析和协程客户端

司马同
2023-12-01

MQTT 是一种基于公布/订阅(publish/subscribe)模式的”轻量级”通信协定,作为一种低开销、低带宽占用的即时通讯协定,曾经成为物联网的重要组成部分

Swoole 也给 PHP 提供了开发物联网我的项目的能力,只须要设置一个 open_mqtt_protocol 选项,启用后就会解析 MQTT 包头,在 Worker 过程的 onReceive 事件每次都会返回一个残缺的 MQTT 数据包

当然其余的也有,例如 Workerman 之前提供的 异步 mqtt 客户端库 ,还有其余的开源库,这里就不一一介绍了

Simps 的第一个版本 MQTT 库 就是参考了 Workerman 的实现,使其可能应用 Swoole 的协程能力,同时也修复了一些问题

在此也要感激 @walkor 对 PHP 生态作出的奉献

第一个版本的实现是放在了框架当中,限度了一些用户的应用。于是又开始了重构,将 MQTT 独立为一个 library ,不便用户应用的同时也丰盛了 PHP 生态,让 PHP 程序员不再局限于 Web 开发

在第一个版本公布之后,Simps 的交换群中也有不少用户询问 MQTT 的问题,Swoole 也修复了一些相干的 Bug,当初应用 PHP + Swoole 去开发物联网相干的我的项目应该是锦上添花

同时第一个版本的 MQTT 库,只反对 MQTT 3.x,不反对 MQTT 5.0,在 GitHub 上也没有找到相干反对的类库,所以在重构了 3.x 版本之后,也反对了一下 MQTT 5.0

兴许这是第一个反对 MQTT v5.0 协定的 PHP library…

反对 MQTT 协定 3.1、3.1.1 和 5.0 版本,反对 QoS 0、QoS 1、QoS 2,那么它来了,应用 composer 来装置

composer require simps/mqtt

装置胜利之后咱们来看一下订阅和公布的应用,以 MQTT5.0 为例

订阅

首先应该是订阅,订阅胜利之后能力收到对应主题的公布音讯,创立一个subscribe.php写入以下内容

include __DIR__ . '/vendor/autoload.php';

use Simps\MQTT\Hex\ReasonCode;

use Swoole\Coroutine;

use Simps\MQTT\Client;

use Simps\MQTT\Types;

$config = [

'host' => 'broker.emqx.io',

'port' => 1883,

'time_out' => 5,

'user_name' => 'user001',

'password' => 'hLXQ9ubnZGzkzf',

'client_id' => Client::genClientID(),

'keep_alive' => 10,

'properties' => [

'session_expiry_interval' => 60,

'receive_maximum' => 200,

'topic_alias_maximum' => 200,

],

'protocol_level' => 5,

];

Coroutine\run(function () use ($config) {

$client = new Client($config, ['open_mqtt_protocol' => true, 'package_max_length' => 2 * 1024 * 1024]);

while (!$data = $client->connect()) {

Coroutine::sleep(3);

$client->connect();

}

$topics['simps-mqtt/user001/get'] = [

'qos' => 1,

'no_local' => true,

'retain_as_published' => true,

'retain_handling' => 2,

];

$timeSincePing = time();

$res = $client->subscribe($topics);

// 订阅的后果

var_dump($res);

while (true) {

$buffer = $client->recv();

if ($buffer && $buffer !== true) {

$timeSincePing = time();

// 收到的数据包

var_dump($buffer);

}

if (isset($config['keep_alive']) && $timeSincePing < (time() - $config['keep_alive'])) {

$buffer = $client->ping();

if ($buffer) {

echo 'send ping success' . PHP_EOL;

$timeSincePing = time();

} else {

$client->close();

break;

}

}

// QoS1 公布回复

if ($buffer['type'] === Types::PUBLISH && $buffer['qos'] === 1) {

$client->send(

[

'type' => Types::PUBACK,

'message_id' => $buffer['message_id'],

'code' => ReasonCode::SUCCESS

]

);

}

}

});

执行php subscribe.php,就会失去这样的输入

array(3) {

["type"]=>

int(9)

["message_id"]=>

int(1)

["codes"]=>

array(1) {

[0]=>

int(1)

}

}

示意订阅胜利,codes 对应的是对应订阅主题的 QoS 等级

公布

订阅胜利之后,创立一个publish.php来测试公布

include __DIR__ . '/vendor/autoload.php';

use Swoole\Coroutine;

use Simps\MQTT\Client;

$config = [

'host' => 'broker.emqx.io',

'port' => 1883,

'time_out' => 5,

'user_name' => 'user002',

'password' => 'adIJS1D482sd',

'client_id' => Client::genClientID(),

'keep_alive' => 20,

'properties' => [

'session_expiry_interval' => 60,

'receive_maximum' => 200,

'topic_alias_maximum' => 200,

],

'protocol_level' => 5,

];

Coroutine\run(function () use ($config) {

$client = new Client($config, ['open_mqtt_protocol' => true, 'package_max_length' => 2 * 1024 * 1024]);

while (!$client->connect()) {

Coroutine::sleep(3);

$client->connect();

}

while (true) {

$response = $client->publish(

'simps-mqtt/user001/get',

'{"time":' . time() . '}',

1,

0,

0,

['topic_alias' => 1]

);

var_dump($response);

Coroutine::sleep(3);

}

});

代码的意思是每隔 3 秒给订阅的主题simps-mqtt/user001/get公布一次音讯

关上一个新的终端窗口,执行php publish.php就会失去输入:

array(4) {

["type"]=>

int(4)

["message_id"]=>

int(1)

["code"]=>

int(0)

["message"]=>

string(7) "Success"

}

这里减少了 message,为了用户可读,不须要去查找对应的 code 含意是什么

返回到订阅的窗口,就会看到所打印的公布信息

array(8) {

["type"]=>

int(3)

["topic"]=>

string(0) ""

["message"]=>

string(19) "{"time":1608017156}"

["dup"]=>

int(1)

["qos"]=>

int(1)

["retain"]=>

int(0)

["message_id"]=>

int(4)

["properties"]=>

array(1) {

["topic_alias"]=>

int(1)

}

}

这样一个简略的公布订阅性能就实现了

在这个库中还有一些值得优化和还未实现的局部,如还没有反对 MQTT5 的Auth type,以及局部的properties还未反对

想参加的同学能够提交 PR,如果有问题也能够提交 Issue,让咱们独特去建设 PHP 的生态

仓库地址:simps/mqtt ,反对记得点个 Star 哦

 类似资料: