PHP MQTT v1.4.0 版本发布,新增 getLevel API 用于解析多个等级协议类型

PHPMQTT v1.4.0 版本发布,新增 getLevel API 用于解析多个等级协议类型

MQTT 有 3 个常用的协议等级:v3.1、v3.1.1 和 v5.0,那么如何在一个端口上同时处理 3 种协议等级的解析呢?

例如在 1883 端口上,同时处理 v3.1、v3.1.1 和 v5.0 这 3 种协议等级

simps/mqtt 提供了 MQTT 协议解析的能力,这种需求在之前的版本中也是可以实现的,不过比较麻烦,可能需要这样:

use Simps\MQTT\Protocol\V3;
use Simps\MQTT\Protocol\V5;

$server->on('receive', function (Swoole\Server $server, $fd, $from_id, $data) {
    try {
        $data = V3::unpack($data);
    } catch (\Throwable $e) {
        try {
            $data = V5::unpack($data);
        } catch (\Throwable $e) {
            throw $e;
        }
    }
    var_dump($data);
});

解析两次数据来进行尝试获取,代码不够优雅

那么现在呢,很简单。安装 simps/mqtt 最新版 v1.4.0,增加了一个getLevel的方法

  • 使用 composer 加载 simps/mqtt
    composer require simps/mqtt
    
  • 创建一个 Server
    use Simps\MQTT\Protocol\Types;
    use Simps\MQTT\Protocol\V3;
    use Simps\MQTT\Protocol\V5;
    use Simps\MQTT\Tools\UnPackTool;
    use Simps\MQTT\Protocol\ProtocolInterface;
    
    $server = new Swoole\Server('127.0.0.1', 1883, SWOOLE_BASE);
    
    $server->set(
        [
            'open_mqtt_protocol' => true,
            'worker_num' => 1,
            'package_max_length' => 2 * 1024 * 1024,
        ]
    );
    
    $server->on('connect', function ($server, $fd) {
        echo "Client #{$fd}: Connect.\n";
    });
    
    $server->on('receive', function (Swoole\Server $server, $fd, $from_id, $data) {
        $type = UnPackTool::getType($data);
        if ($type === Types::CONNECT) {
            $level = UnPackTool::getLevel($data);
            $class = $level === ProtocolInterface::MQTT_PROTOCOL_LEVEL_5_0 ? V5::class : V3::class;
            $server->fds[$fd] = ['level' => $level, 'class' => $class];
        }
        /** @var ProtocolInterface $unpack */
        $unpack = $server->fds[$fd]['class'];
        var_dump($unpack::unpack($data));
    });
    
    $server->on('close', function ($server, $fd) {
        unset($server->fds[$fd]);
        echo "Client #{$fd}: Close.\n";
    });
    
    $server->start();
    

这样代码就看起来简单多了,使用 getType 获取当前包的类型,在 connect 类型的时候获取使用协议类型是什么,

然后存到$server->fds 中,下文就可以从直接取对应的协议解析类来进行处理。

$type = UnPackTool::getType($data);
if ($type === Types::CONNECT) {
    $level = UnPackTool::getLevel($data);
    $class = $level === ProtocolInterface::MQTT_PROTOCOL_LEVEL_5_0 ? V5::class : V3::class;
}

五行代码就可以实现这个功能需求~

「点点赞赏,手留余香」

1

给作者打赏,鼓励TA抓紧创作!

微信微信 支付宝支付宝

还没有人赞赏,快来当第一个赞赏的人吧!

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
码云笔记 » PHP MQTT v1.4.0 版本发布,新增 getLevel API 用于解析多个等级协议类型

发表回复