MQTT服务端的控制器,主要用于代替消息事件中,分离业务逻辑的相关代码。
由于某些物联网项目,不单止用于客户端间通讯,更多需要用到服务端的业务查询、判断、主动推流等,所以在消息事件中对某个流程的代码分离,是非常重要的,便于日后的代码维护、版本迭代。
MQTT的控制器文件,统一存放在/app/mqtt/
目录下,需要继承\x\controller\Mqtt
系统类。
命名方式不强制大小写,但建议遵守以为标准:
框架不会自动载入MQTT服务的控制器,需要开发者在消息事件中手动挂载,具体可以参考:挂载业务控制器说明。
在MQTT的控制器中,可以使用$this->getServer()
方法,获取当前Swoole-Server的Class实例。
该方法的返回值是一个对象。
在MQTT的控制器中,可以使用$this->getFd()
方法,获取当前连接设备的Swoole-fd的连接标识符。
该方法的返回值是一个int
类型的标识符。
在MQTT的控制器中,可以使用$this->getReactorId()
方法,获取当前连接设备所处Swoole的线程ID。
该方法的返回值是一个int
类型的线程ID。
在MQTT的控制器中,可以使用$this->getData()
方法,获取当前连接所发布的消息内容。
该方法的返回值是一个多维数组。
在MQTT的控制器中,可以使用$this->select(订阅主题名称)
方法,搜索某个主题下的全部设备号。
该方法的返回值是一个多维数组。若无结果,返回一个空数组。
结果格式如下:
[
[
fd => 连接标识符
client_id => 客户端设备号
topic => 订阅主题
qos => QOS
]
]
订阅主题名称支持MQTT通配符的使用。
在MQTT的控制器中,可以使用$this->find(设备号)
方法,搜索某个设备号的当前详情。
该方法的返回值是一个多维数组。若无结果,返回一个空数组。
结果格式如下:
[
fd => 连接标识符
level => 协议版本 3|5
status => 在线状态 1.在线 2.离线
client_id => 客户端设备号
ping_time => 最近一次心跳检测时间戳
list => [
[
topic => 订阅主题名称
qos => QOS
]
]
]
在MQTT的控制器中,可以使用$this->info()
方法,读取当前连接的设备详情。
该方法的返回值是一个多维数组。若无结果,返回一个空数组。
结果格式如下:
[
fd => 连接标识符
level => 协议版本 3|5
status => 在线状态 1.在线 2.离线
client_id => 客户端设备号
ping_time => 最近一次心跳检测时间戳
list => [
[
topic => 订阅主题名称
qos => QOS
]
]
]
在MQTT的控制器中,可以使用$this->send(FD标识符, 推送内容)
方法,对某个客户端设备进行消息推送。
该方法的返回值是一个Bool
值。
注意:参数2,推送内容是一个多维数组,其中type
参数,必须读取\x\mqtt\common\Tyeps
消息事件类中的标识符,否则消息将可能发送失败。
具体的使用案例,参考如下:
namespace app\mqtt\system;
use x\controller\Mqtt;
// 引入MQTT消息标识符类
use x\mqtt\common\Tyeps;
class index extends Mqtt {
public function run() {
$data = $this->getData();
// 给当前请求推送一条消息回去
$this->send($this->getFd(), [
'type' => Types::PUBLISH,
'topic' => $data['topic'],
'message' => $data['message'],
'dup' => $data['dup'],
'qos' => $data['qos'],
'retain' => $data['retain'],
'message_id' => $data['message_id'] ?? '',
]
);
}
}
注意:在Types::PUBLISH
中,message
字段为客户端接受到的消息内容主体。
v2.5.6
版本起支持,在MQTT的控制器中,可以使用$this->getLevel()
方法,获取当前连接对应的协议版本信息。
该方法的返回值是一个多维数组,结构如下:
[
'level' => 5, // 协议版本号
'class' => '\x\mqtt\v3\Dc', // 数据包处理类的命名空间地址
]