QMQTT 实现是基于 MQTT 协议标准编写的 Delphi 客户端程序,不依赖于任何第三方的 DLL 或组件实现。它的主要特性如下:
- 完整支持 MQTT 3.1.1 协议版本(5.0版也将支持)
- 不依赖任何第三方组件(QDAC 内也只是依赖于 QString 单元)
- 支持主题的多重派发,也就是说同一个主题在程序中,并不要求只有一个响应者,多个响应者不需要手工协调(如:保存前一个响应者)
- 所有事件均在主线程中触发,不需要用户去处理线程同步的问题(至地你将处理的过程再转到后台处理线程,那就是另一回事)
- 断线自动重连,不需要人工干予
- 可以直接开启日志记录选项(通过条件编译打开,需要引用 QLog 单元,事实上作者曾考虑引用下 QJson 单元,不过感觉实际上外部也就多写一个解析 TopicText,而且重用性更好暂时放弃)
- TQMQTTMessage 结构封装多种方法对数据进行解码,方便开发过程。
关于 MQTT 标准规范,请浏览 MQTT 官方网站,中文翻译版本。
MQTT是一个客户端服务端架构的发布/订阅模式的消息传输协议。它的设计思想是轻巧、开放、简单、规范,易于实现。这些特点使得它对很多场景来说都是很好的选择,特别是对于受限的环境如机器与机器的通信(M2M)以及物联网环境(IoT)。
支持 MQTT 协议的消息中间件有很多,我测试是基于 RabbitMQ 测试的。目前已知的消息中间件服务器相当不少,有一个网站对比了它们的特性,详细内容可以访问 GitHub 地址。
Server | QoS 0 | QoS 1 | QoS 2 | auth | bridge | $SYS | SSL | dynamic topics | cluster | websockets | plugin system |
---|---|---|---|---|---|---|---|---|---|---|---|
2lemetry | ✔ | ✔ | ✔ | ✔ | ✔ | § | ✔ | ✔ | ✔ | ✔ | ✘ |
Jmqtt | ✔ | ✔ | ✔ | ✔ | ✔ | § | § | ✔ | § | ✔ | ✔ |
Apache ActiveMQ | ✔ | ✔ | ✔ | ✔ | ✘ | ✘ | ✔ | ✔ | ✔ | ✔ | ✔ |
Apache ActiveMQ Artemis | ✔ | ✔ | ✔ | ✔ | ✘ | ✘ | ✔ | ✔ | ✔ | ✔ | ✔ |
Bevywise IoT Platform | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | rm |
emitter | ✔ | § | ✘ | ✔ | ✘ | ✘ | ✔ | ✔ | ✔ | ✔ | ✘ |
emqttd | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
flespi | ✔ | ✔ | ✔ | ✔ | ✘ | ✘ | ✔ | ✔ | ✔ | ✔ | ✘ |
GnatMQ | ✔ | ✔ | ✔ | ✔ | ✘ | ✘ | ✘ | ✔ | ✘ | ✘ | ✘ |
HBMQTT | ✔ | ✔ | ✔ | ✔ | ✘ | ✔ | ✔ | ✔ | ✘ | ✔ | ✔ |
HiveMQ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
IBM MessageSight | ✔ | ✔ | ✔ | ✔ | ✘ | ✔ | ✔ | ✔ | § | ✔ | ✘ |
JoramMQ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
Mongoose | ✔ | ✔ | ? | ? | ? | ? | ? | ? | ? | ? | ? |
moquette | ✔ | ✔ | ✔ | ✔ | ? | ? | ✔ | ? | rm | ✔ | ✘ |
mosca | ✔ | ✔ | ✘ | ✔ | ? | ? | ? | ? | ✘ | ✔ | ✘ |
mosquitto | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | § | ✔ | ✔ |
MQTT.js | ✔ | ✔ | ✔ | § | ✘ | ✘ | ✔ | ✔ | ✘ | ✔ | ✘ |
MqttWk | ✔ | ✔ | ✔ | ✔ | ✔ | ? | ✔ | ✔ | ✔ | ✔ | ✘ |
RabbitMQ | ✔ | ✔ | ✘ | ✔ | ✘ | ✘ | ✔ | ✔ | ? | ? | ? |
RSMB | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✘ | ✔ | ✘ | ✘ | ? |
Software AG Universal Messaging | ✔ | ✔ | ✔ | ✔ | ✘ | ✘ | ✔ | ✔ | ✔ | rm | ✘ |
Solace | ✔ | ✔ | ✘ | ✔ | § | ✔ | ✔ | ✔ | ✔ | ✔ | ✘ |
SwiftMQ | ✔ | ✔ | ✔ | ✔ | ✔ | ✘ | ✔ | ✔ | ✔ | ✘ | ✔ |
Trafero Tstack | ✔ | ✔ | ✔ | ✔ | ✘ | ✘ | ✔ | ✔ | ✘ | ✘ | ✘ |
VerneMQ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
WebSphere MQ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ? |
MQTT 网上公开可用的测试服务器可以访问下面的链接:
https://github.com/mqtt/mqtt.github.io/wiki/public_brokers
嗯,废话有点多,我们回到本文主题,QMQTT 客户端组件,它只有一个QMQTTClient 单元,但需要 QString 单元支持(当然如果你嫌 QString 太大,大可以将相关函数挪过来)。
【使用方法】
- 创建一个 TQMQTTMessageClient 实例,并设置相关参数。也可以直接用全局的 DefaultMQTTClient 实例当然全局实例不需要你自己释放。注意暂时 QMQTT 不支持 SSL 连接。
- 调用 RegisterDispatch 关联主题与处理函数之间的关系。
- 调用 Subscribe 函数添加订阅,注意如果网络没有连接,则不会实际注册,在网络连接后会自动注册。
- 调用 Start 启动客户端。
- 要发布主题,调用 Publish 方法发布
- 停止连接可以调用 Stop 方法。
【提示】 TQMQTTMessageClient 继承自 TComponent ,所以你也可以创建时指定一个 Owner,这样它就会跟随对应的组件一起释放了。
综合上面的步骤,QMQTT 对于我们用户核心在于调用 RegisterDispatch 处理具体的消息,所以这里重点就此做出说明。至于其它函数的用户,请参考示例中的相关代码。
我们先看一下 RegisterDispatch 函数的声明:
procedure RegisterDispatch(const ATopic: String;AHandler: TQMQTTTopicDispatchEvent;AType: TTopicMatchType = mtFull); overload;
- ATopic 参数指明要匹配的主题,或者是主题的过滤表达式或正则表达式。关于过滤表达式的格式 ,请参考官方标准规范里的说明。至于正则表达式,自己百度去吧。
- AHandler 参数指明收到指定的主题时,要调用的处理函数(匿名函数和全局函数版本暂时不支持)。
- AType 参数指明匹配模式,默认值 mtFull 为精确匹配,mtPattern 为过滤表达式匹配,mtRegex 为正则表达式匹配。
下面是示例代码:
FClient.RegisterDispatch('/Topic/Dispatch', DoStdTopicTest);
FClient.RegisterDispatch('/+/Dispatch', DoPatternTopicTest, mtPattern);
FClient.RegisterDispatch('/Topic\d', DoRegexTopicTest, mtRegex);
然后我们只需要在对应的处理函数中做具体的处理即可。