扫码阅读
手机扫码阅读
MQTT 怎么在单独一个端口上分别使用 v3.x 和 v5.0 协议解析?
225 2023-07-18
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;
}
五行代码就可以实现这个功能需求~ 如果你被加鸡腿了不要忘了我哦 :)
分享一个讲解 MQTT 协议的 PPT,你可以不限速下载 ????
链接:https://www.aliyundrive.com/s/YUW7P2aDQZU
原文链接:
http://mp.weixin.qq.com/s?__biz=MzAwOTgzNjY4MA==&mid=2247484216&idx=1&sn=6e5ff4c04cbd5f11b0a676f39638b060&chksm=9b58c2dfac2f4bc9832393cc8019620075c50d2f9b9f09a3452f3ffe1576bc73cc61a35f1fe1#rd
鲁飞的其他文章
怎么复用 GitHub Actions 的 Workflows
使工作流程可重复使用,而不是从一个工作流程复制并粘贴到另一个工作流程。 自己和有权访问可重用工作流程的任何人都可以从另一个工作流程调用可重用工作流程。
GitHub Actions 真香系列之scp和ssh
虽然现在有 k8s 作为部署服务,但也有一部分的业务还是使用传统的方式,在服务器上使用 LNMP 进行部署 Web 站点。
你不知道的PHP小技巧之计算文本相似度
有这样一个需求:需要对于用户发布的内容标题进行相似度对比,如果有之前的内容和当前发布的内容标题相似度到达某个阈值时则禁止发布或进行其他的一些操作。
Think-Swoole如何设置Swoole提供的配置项
think-swoole 的文档极少,官方文档中也只是说了如何启动、热更新、连接池等配置
Nginx目录浏览并进行美化
Nginx 作为一个高性能的 HTTP 和反向代理 web 服务器,默认不允许列出站点的整个目录,如果需要开启,可以通过配置打开此功能。
加入社区微信群
与行业大咖零距离交流学习
软件研发质量管理体系建设
白皮书上线