在 imi 框架中开发 MQTT 服务端,并且内置了一个 MQTT 客户端。
MQTT是一个基于客户端-服务器的消息发布/订阅传输协议。MQTT协议是轻量、简单、开放和易于实现的,这些特点使它适用范围非常广泛。在很多情况下,包括受限的环境中,如:机器与机器(M2M)通信和物联网(IoT)。其在,通过卫星链路通信传感器、偶尔拨号的医疗设备、智能家居、及一些小型化设备中已广泛使用。
本仓库仅用于浏览,不接受 issue 和 Pull Requests,请前往:https://github.com/imiphp/imi
本项目可以使用composer安装,遵循psr-4自动加载规则,在你的 composer.json
中加入下面的内容:
{
"require": {
"imiphp/imi-mqtt": "~2.0.0"
}
}
然后执行 composer update
安装。
可以参考
example
、tests
目录示例。
项目配置文件:
[
'components' => [
'MQTT' => 'Imi\MQTT',
],
]
imi-mqtt
基于 binsoul/net-mqtt
开发,使用的都是这个包中的数据包结构类。
类名一般是BinSoul\Net\Mqtt\Packet\XXX
如:\BinSoul\Net\Mqtt\Packet\SubscribeRequestPacket
首先,服务器配置的type
设为MQTT
,并且定义好控制器。
控制器需要继承Imi\Server\MQTT\BaseMQTTController
类,并且实现方法。
如果你是主服务器,配置如下:
'mainServer' => [
'namespace' => 'ImiApp\MQTTServer',
'type' => 'MQTTServer',
'host' => '127.0.0.1',
'port' => 8081,
'controller' => \ImiApp\MQTTServer\Controller\MQTTController::class,
// 'configs' => [
// // 启用 MQTTS 配置证书
// 'ssl_cert_file' => dirname(__DIR__) . '/ssl/server.crt',
// 'ssl_key_file' => dirname(__DIR__) . '/ssl/server.key',
// ],
],
如果你是子服务器,配置如下下:
// 子服务器(端口监听)配置
'subServers' => [
'xxxServer' => [
'namespace' => 'ImiApp\MQTTServer',
'type' => 'MQTTServer',
'host' => '127.0.0.1',
'port' => 8081,
'controller' => \ImiApp\MQTTServer\Controller\MQTTController::class,
// 'configs' => [
// // 启用 MQTTS 配置证书
// 'ssl_cert_file' => dirname(__DIR__) . '/ssl/server.crt',
// 'ssl_key_file' => dirname(__DIR__) . '/ssl/server.key',
// ],
],
],
在控制器方法中返回一个包对象,代表响应当前请求。
同样支持\Imi\Server\Server::send()
等方法,详见:https://doc.imiphp.com/v2.0/utils/Server.html
事件监听类:
<?php
namespace Imi\MQTT\Test;
use Imi\MQTT\Client\Contract\IMQTTClientListener;
class TestClientListener implements IMQTTClientListener
{
/**
* 连接确认
*
* @param \Imi\MQTT\Client\MQTTClient $client
* @param \BinSoul\Net\Mqtt\Packet\ConnectResponsePacket $packet
* @return void
*/
public function connectACK(\Imi\MQTT\Client\MQTTClient $client, \BinSoul\Net\Mqtt\Packet\ConnectResponsePacket $packet)
{
}
/**
* 发布
*
* @param \Imi\MQTT\Client\MQTTClient $client
* @param \BinSoul\Net\Mqtt\Packet\PublishRequestPacket $packet
* @return void
*/
public function publish(\Imi\MQTT\Client\MQTTClient $client, \BinSoul\Net\Mqtt\Packet\PublishRequestPacket $packet)
{
}
/**
* 发布确认
*
* @param \Imi\MQTT\Client\MQTTClient $client
* @param \BinSoul\Net\Mqtt\Packet\PublishAckPacket $packet
* @return void
*/
public function publishAck(\Imi\MQTT\Client\MQTTClient $client, \BinSoul\Net\Mqtt\Packet\PublishAckPacket $packet)
{
}
/**
* 发布已收到(保证交付部分1)
*
* @param \Imi\MQTT\Client\MQTTClient $client
* @param \BinSoul\Net\Mqtt\Packet\PublishReceivedPacket $packet
* @return void
*/
public function publishReceived(\Imi\MQTT\Client\MQTTClient $client, \BinSoul\Net\Mqtt\Packet\PublishReceivedPacket $packet)
{
}
/**
* 发布释放(确保交付的第2部分)
*
* @param \Imi\MQTT\Client\MQTTClient $client
* @param \BinSoul\Net\Mqtt\Packet\PublishReleasePacket $packet
* @return void
*/
public function publishRelease(\Imi\MQTT\Client\MQTTClient $client, \BinSoul\Net\Mqtt\Packet\PublishReleasePacket $packet)
{
}
/**
* 发布完成(保证交付的第3部分)
*
* @param \Imi\MQTT\Client\MQTTClient $client
* @param \BinSoul\Net\Mqtt\Packet\PublishCompletePacket $packet
* @return void
*/
public function publishComplete(\Imi\MQTT\Client\MQTTClient $client, \BinSoul\Net\Mqtt\Packet\PublishCompletePacket $packet)
{
}
/**
* 订阅确认
*
* @param \Imi\MQTT\Client\MQTTClient $client
* @param \BinSoul\Net\Mqtt\Packet\SubscribeResponsePacket $packet
* @return void
*/
public function subscribeACK(\Imi\MQTT\Client\MQTTClient $client, \BinSoul\Net\Mqtt\Packet\SubscribeResponsePacket $packet)
{
}
/**
* 取消订阅确认
*
* @param \Imi\MQTT\Client\MQTTClient $client
* @param \BinSoul\Net\Mqtt\Packet\UnsubscribeResponsePacket $packet
* @return void
*/
public function unsubscribeACK(\Imi\MQTT\Client\MQTTClient $client, \BinSoul\Net\Mqtt\Packet\UnsubscribeResponsePacket $packet)
{
}
/**
* Ping 响应
*
* @param \Imi\MQTT\Client\MQTTClient $client
* @param \BinSoul\Net\Mqtt\Packet\PingResponsePacket $packet
* @return void
*/
public function ping(\Imi\MQTT\Client\MQTTClient $client, \BinSoul\Net\Mqtt\Packet\PingResponsePacket $packet)
{
}
}
客户端调用:
use Imi\MQTT\Client\MQTTClient;
$client = new MQTTClient([
'host' => '127.0.0.1',
'port' => 8081,
], new TestClientListener);
$client->wait(); // 开始循环接收,直到关闭连接
客户端参数表:
参数名 | 说明 |
---|---|
host | 服务器主机名称 |
port | 服务器端口号 |
timeout | 网络通讯超时时间 |
pingTimespan | 定时 ping 的时间间隔,单位秒。默认为 NULL 则不自动 ping |
protocol | 协议级别,默认4 。3-MQIsdp;4-MQTT |
username | 用户名 |
password | 密码 |
clientId | 客户端ID |
keepAlive | 保活时间 |
clean | 清除会话 |
will | 遗嘱消息,具体结构看下面的表格 |
ssl | 使用 SSL 连接 |
sslCertFile | 证书文件 |
sslKeyFile | 证书密钥文件 |
sslVerifyPeer | 验证服务器端证书 |
sslAllowSelfSigned | 允许自签名证书 |
sslHostName | 服务器主机名称 |
sslCafile | CA 证书 |
sslCapath | 证书目录 |
will 遗嘱消息参数表:
参数名 | 说明 |
---|---|
topic | 主题 |
payload | 有效载荷 |
qosLevel | 0-最多一次的传输;1-至少一次的传输;2-只有一次的传输 |
retain | 保留 |
duplicate | 重复 |
imi-mqtt
遵循 MIT 开源协议发布,并提供免费使用。
开源不求盈利,多少都是心意,生活不易,随缘随缘……