SW-X对MQTT服务端的消息事件进行了转发和重写,MQTT服务端的消息事件,统一存放在/box/event/mqtt/
目录下,文件名称为对应消息的事件名。
以下为MQTT服务端事件的总览:
// 双方握手时
Connect.php
// 断开连接时
Disconnect.php
// 心跳请求时
Pingreq.php
// 发布消息时-(主要业务逻辑都在这里挂载控制器)
Publish.php
// 订阅主题时
Subscribe.php
// 取消订阅时
UnSubscribe.php
在MQTT的消息事件类中,我们可以使用$this->getServer()
方法,获取当前Swoole-Server的Class实例。
该方法的返回值是一个对象。
在MQTT的消息事件类中,我们可以使用$this->getFd()
方法,获取当前连接设备的Swoole-fd的连接标识符。
该方法的返回值是一个int
类型的标识符。
使用该连接标识符可以对客户端进行消息发布。
在MQTT的消息事件类中,我们可以使用$this->getReactorId()
方法,获取当前连接设备所处Swoole的线程ID。
该方法的返回值是一个int
类型的线程ID。
在MQTT的消息事件类中,我们可以使用$this->getData()
方法,获取当前连接所发布的消息内容。
该方法的返回值是一个多维数组。
v2.5.6
版本起支持,在MQTT的消息事件类中,我们可以使用$this->getLevel()
方法,获取当前连接对应的协议版本信息。
该方法的返回值是一个多维数组,结构如下:
[
'level' => 5, // 协议版本号
'class' => '\x\mqtt\v3\Dc', // 数据包处理类的命名空间地址
]
在MQTT的消息事件类中,开发通常会自定义一些与项目相关的业务逻辑,这时候就需要用到控制器转发功能,进行业务隔离。
使用$this->controller(控制器地址,方法)
的方式来进行控制器挂载,
注意:参数1,控制器地址,不需要带/app/mqtt/
前置命名空间名称。
注意:参数2,当为空时,默认加载index
方法。
下面以Publish
消息事件中的Demo代码为例:
namespace box\event\mqtt;
use x\mqtt\base\Event;
use x\mqtt\common\Types;
class Publish extends Event {
/**
* 说明:
* $this->getServer() : 获取Swoole实例
* $this->getFd() : 获取当前请求标示符
* $this->getData() : 获取已解码后的数据包
* $this->getReactorId : 获取当前请求所处的线程ID
* $this->getLevel : 获得协议类型信息
*/
/**
* 事件处理入口
* @todo 无
* @author 小黄牛
* @version v2.0.11 + 2021.07.02
* @deprecated 暂不启用
* @global 无
* @return void
*/
public function run() {
// 这里可以使用controller,挂载控制器
// 控制器,方法[默认index]
// $this->controller('system/index');
// 获得协议处理类
$arr = $this->getLevel();
$class = $arr['class'];
// 默认的广播示例控制器
$this->controller('system/index', 'run');
// // 处理完成后需要回复以下内容
$data = $this->getData();
if ($data['qos'] === 1) {
$this->getServer()->send(
$this->getFd(),
$class::pack([
'type' => Types::PUBACK,
'message_id' => $data['message_id'] ?? '',
])
);
}
}
}