1.一套极简的MQTT使用接口EasyMqttClient
2.统信UOS系统开发笔记(八):在统信UOS上编译搭建mqtt基础环境(版本使用QMQTT::Clinet)
3.编写基于paho-mqtt-c客户端用openssl证书连接mqtt broker
4.5-Openwrt MQTT client使ç¨
5.如何为 Mosquitto MQTT 代理启用 WebSocket?
6.ESP32采集DHT11温度到公共MQTT服务器,NODE-RED图形化显示。
一套极简的MQTT使用接口EasyMqttClient
在物联网开发中,EasyMqttClient是一个高效的MQTT接口,它基于杰杰大佬的mqttclient进行了简化。起初,194源码我发现存在内存泄露问题,主要在mqttclient/platform/linux/platform_thread.c的platform_thread_destroy函数中,由于缺乏对线程资源的释放,mqtt_release可能导致内存泄漏。此外,mqtt_common/log模块也有内存泄露,通过关闭MQTT_LOG_IS_SALOF可以解决。
尽管mqtt_release场景不常见,但为确保稳定,我已针对这些问题进行了修复。EasyMqttClient的核心在于其极简的API设计,只有7个,使得初始化(如设置URL和端口)变得更加直观。它还采用了结构体数组,根据Topic订阅的不同,自动调用相应的回调函数,提高了代码的清晰度和可维护性。
EasyMqttSubscribe函数允许用户订阅Topic,并将其与回调函数关联。易用示例可通过EasyMqtt.c的EasyMqttTest函数找到。目前,该接口已在Linux环境下测试通过,但仍在其他RTOS环境上进行兼容性测试。我们鼓励大家参与,共同优化嵌入式MQTT开发体验。
为了在嵌入式平台运行EasyMqttClient,你需要在Makefile中进行相应配置,starbbs源码如果不做修改,将默认使用gcc编译。其他平台支持仍在测试阶段。
该内容源自嵌入式应用研究院,原始文章可参考:《一套极简的MQTT使用接口EasyMqttClient》。
统信UOS系统开发笔记(八):在统信UOS上编译搭建mqtt基础环境(版本使用QMQTT::Clinet)
MQTT协议介绍
MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议)是基于发布/订阅模式的轻量级通讯协议,由IBM于年发布。其最大优点在于,能以极少的代码和有限的带宽,为连接远程设备提供实时可靠的消息服务。MQTT广泛应用于物联网、小型设备、移动应用等领域。
MQTT设计原则
MQTT具有以下特点:
1. 使用发布/订阅模式,实现一对多的消息发布,解除应用程序耦合。
2. 提供对负载内容的屏蔽,进行消息传输。
3. 使用TCP/IP提供网络连接。
4. 支持三种消息发布服务质量。
5. 具有小型传输、开销小的特性,协议交换最小化。
6. 为客户端异常中断提供机制。
发布/订阅者模式
MQTT支持发布/订阅模式,使MQTT协议在物联网、机器与机器(M2M)通信、智能家居等领域得到广泛应用。
统信UOS系统MQTT编译与环境搭建
统信UOS系统版本:系统版本为统信UOS 。
Qt编译MQTT
Qt5版本开始支持MQTT,但并未集成至安装包,源码recovery需自行下载编译。Qt提供的qtmqtt库不支持点对点方式,仅支持订阅/发布者模式。
编译步骤
下载并解压MQTT源码至目标系统。
使用QtQCreator打开pro工程编译,切换至release模式。
在解压的源码路径手动创建Qt5Mqtt文件,编译成功。
部署MQTT模块至qt
将MQTT源码融入qt工程中,实现模块化部署。新建mqttClientDemo工程,提取源码中的mqtt模块,将其加入新工程的modules,引入qmqtt.pri文件。
解决编译报错
编译报错时,添加缺失的网络模块(QT += network),并调整私有头文件宏至头文件宏。
源码融入编译成功
源码成功融入,后续无需重新编译即可替换系统或版本。
模块化部署优化
创建mqttClientManager管理模块,用于包含MQTT源码,实现模块化部署。
编写基于paho-mqtt-c客户端用openssl证书连接mqtt broker
编写基于paho-mqtt-c客户端使用openssl证书连接mqtt broker,涉及broker、消息、超时、持久化等概念。以下代码示例说明其过程。
初始化OpenSSL库并创建SSL上下文是第一步。紧接着,设置MQTTClient_SSLOptions结构体的选项,包括启用服务器证书认证、javaequals源码使用TLSv1.2协议以及指定信任的CA证书文件路径。
将SSL上下文融入MQTTClient_SSLOptions,并将此设置传递给MQTTClient_connectOptions结构体。最后一步,执行连接MQTT broker操作并发送消息。
重要提示:此示例代码仅为参考,实际应用中需根据具体情况进行调整。具体配置OpenSSL证书及其文件路径等,需依据实际情况。
5-Openwrt MQTT client使ç¨
å¨mosquittoéé¢æ个clientç®å½ï¼éé¢å°±æ¯ä½¿ç¨libmosquittoå®ç°ç客æ·ç«¯ç¨åºï¼å°è£ æmosquitto_subåmosquitto_pubå½ä»¤è¡ã
æ以æ°å»ºä¸ä¸ªè·clientåä¸çº§ï¼èªå·±çclientï¼æ·»å 对åºçæ件
Makefileçå 容
main.cçå 容
myclient.hçå 容
å¤å±çmosquitto/src/Makefileéé¢æ·»å myclientæ件çç¼è¯
ç¼è¯æµè¯ä¸åæ£å¸¸ï¼æ¥ä¸å»æ·»å mqttçå 容
mqtt clientéé¢æ主è¦çå°±æ¯å 个åè°å½æ°ï¼å è°ç¨lib_init,æ£å¸¸åï¼å°±è¿åªå个callbackï¼ç¶åå¨callbackéé¢åé»è¾ã
ååè°å½æ°çå 容
é»è¾åºè¯¥ä¹æ¯è¾ç´è§ï¼å½connectæååï¼å¨åè°å½æ°éé¢è®¢é test1主é¢çå 容ï¼ç¶ååå¸test2主é¢çå 容ã
æ¶å°å å®¹å°±å¨ myclient_message_callback åè°éé¢æå°å¤çã
æ£å¸¸æ åµæ们é½ä¼è®©å®¢æ·ç«¯çè¿æ¥åä¸äºè´¦å·å¯ç ç设置ï¼é¿å å«äººæ»å»ã
å°allow_anonymousæ¹æä¸å 许å¿åç»éï¼å¹¶å¶å®pwfileã
vim /etc/mosquittoConf/mosquitto.conf
å¨ubuntuä¸é¢ä½¿ç¨mosquitto_passwdçæå¯ç
å°±ä¼å¨pwfileæ件ä¸çæè´¦å·åå å¯çå¯ç root/admin
è¿æ¯åç»éçæ¶åå°±éè¦-u root -P adminè¿è¡ç»é
mosquittoæä¾äºmosquitto_passwdå½ä»¤æ¥çæè´¦å·å¯ç çï¼ä¸è¿è¿ä¸ªæ¹å¼ä¸å欢ï¼å 为没åæ³å®å¶åèªå·±æ³è¦çè´¦å·å¯ç å å¯æ¹å¼ï¼æ以åäºä¸äºå°æ¹å¨ã
å¨myclientéé¢å æ们æ³è¦çå å¯æ¹å¼ï¼ç¶åå¨mosquitto brokerçæºç éé¢æ·»å 对åºç解å¯æ¹å¼å³å¯ã
å¦ä¸ï¼è´¦å·ä¸ºclient_nameï¼ç¶åéè¿rsaåbaseçæå¯ç ï¼myclientçè¯ä¸è°ç¨ mosquitto_username_pw_set å½æ°ã
ç¶åå¨mosquitto brokeréé¢æ·»å 解å¯ï¼ä½äºmosquitto/src/security.cæ件ç mosquitto_unpwd_check å½æ°éé¢ã
å¦ä¸ä¸ªå å¯æ¹å¼å°±æ¯SSL认è¯ï¼ç»å®¢æ·ç«¯æä¾ç¸åºçè¯ä¹¦ï¼åé ç½®åè®®(mqtt or websockets)ä¸æ ·ï¼å¨é ç½®æ件çå¬ç端å£ä¸é¢å¯ä»¥æ·»å sslçé ç½®é项ï¼æ¯ä¸ªporté½å¯ä»¥åç¬é ç½®sslçè¯ä¹¦å å容ã
å¦ä¸ï¼ä»ç«¯å£è¿æ¥è¿æ¥ç设å¤éè¦ä¸é¢çè¯ä¹¦è¦æ±
设å¤ç认è¯æåå认è¯ååå认è¯ä¸¤ç§ï¼
åå认è¯ï¼åªéè¦æä¾caè¯ä¹¦
åå认è¯ï¼éè¦ca,pem,keyä¸ä¸ª
ææ¥éª¤ä¸æ¥ä¸æ¥æ§è¡ï¼çæè¯ä¹¦ï¼éé¢ä¹å¯ä»¥æå®ååæ°ï¼æææ¶é´ï¼ï¼
æä¸é¢çæ¥éª¤å¯ä»¥çæå¦ä¸æ件
å¨æå¡å¨ç«¯éè¦æ¾ä¸ä¸ªæ件
å¦ææ¯åå认è¯ï¼å®¢æ·ç«¯åªéè¦ä¸ä¸ªæ件
å¦ææ¯åå认è¯ï¼å®¢æ·ç«¯åªéè¦ä¸ä¸ªæ件
æ¥çè¯ä¹¦çæææ¶é´
如何为 Mosquitto MQTT 代理启用 WebSocket?
WebSocket是一种全双工通信协议,提供实时双向数据传输,对于集成Web应用与MQTT代理服务器尤其有用。Mosquitto作为一款广泛使用的开源MQTT代理,本文将指导您如何将其配置为支持WebSocket,以便通过Web浏览器与MQTT代理服务器进行通信。
启用WebSocket支持后,Web应用可通过JavaScript直接与MQTT代理服务器通信,无需额外客户端库,实现更便捷的实时数据交换。以下是为Mosquitto MQTT代理启用WebSocket的步骤:1. 首先,确保在服务器上安装并配置了Mosquitto MQTT代理。在Ubuntu上,使用以下命令进行安装:
安装完成后,Mosquitto将自动启动并监听默认MQTT端口()。
2. 要启用WebSocket支持,请编辑Mosquitto的配置文件,如Ubuntu上的配置文件位于 /etc/mosquitto/mosquitto.conf。添加以下配置以在端口启用WebSocket服务:
保存配置后,重启Mosquitto服务以使更改生效,具体命令如下:
至此,Mosquitto MQTT代理已配置为支持WebSocket,并在端口监听WebSocket连接。share源码
3. 测试WebSocket连接时,可以使用Web浏览器来验证配置是否生效。通过JavaScript和MQTT over WebSocket库(例如Paho MQTT库)创建WebSocket连接,并与MQTT代理进行通信。以下是一个使用JavaScript实现的简单示例代码:
在代码中,创建了一个名为mqttClient的Paho MQTT客户端对象,通过指定代理服务器地址(mqtt.example.com)和WebSocket连接端口()建立WebSocket连接。设置连接选项,包括超时时间、是否使用SSL,并定义连接成功和失败的回调函数。在连接成功后,可以订阅主题,并在接收到消息时处理消息。最后,通过调用connect方法建立WebSocket连接并连接到MQTT代理。
通过以上步骤,已成功启用Mosquitto MQTT代理的WebSocket支持,并实现Web浏览器与MQTT代理之间的通信。WebSocket为集成MQTT协议与Web技术提供了灵活便捷的方式,尤其适用于物联网应用开发。启用WebSocket支持后,Web开发人员可更方便地构建实时数据交换功能,提升物联网应用的响应速度与用户体验。
ESP采集DHT温度到公共MQTT服务器,NODE-RED图形化显示。
一 免费的公共MQTT服务器参数
二 DHT温湿度传感器
三 ESP-S开发板引脚图
三ESP 采集温度上传公共服务器代码
import dht
import time
import machine
from umqtt.simple import MQTTClient
import network
d = dht.DHT(machine.Pin())
ssid='tp'
passwd='jxl'
client_id = "ESP"
mserver = 'broker.emqx.io'
port=
topic_sta = b'dht_sta'
def connectWiFi():
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.disconnect()
wlan.connect(ssid, passwd)
while(wlan.ifconfig()[0]=='0.0.0.0'):
time.sleep(1)
print('network config:', wlan.ifconfig())
connectWiFi()
client = MQTTClient(client_id, mserver, port)
client.connect()
while True:
d.measure()
data = "temp(c): %s" % d.temperature()
print(data)
client.publish(topic_sta, data, retain=True, qos=0)
time.sleep()
四 测试中发现的问题
1 ESP自带dht库,无需额外下载。
2 使用自建的MQTTX基础版
3 温度值输出不规律,可能与WiFi信号有关,切换后改善但仍有异常。
4 服务器接收数据异常,修改输出格式后解决。
五 node-red 物联网工具
1 安装node.js,确保node -v和npm -v运行无误,使用npm安装node-red。
2 启动Node-RED后台,通过浏览器访问http://localhost:打开界面。
3 安装仪表板,添加按钮、文本、图表节点,通过node-red-dashboard进行安装。
浅谈mqtt源码(二)Client详解
深入探索MQTT源码:客户端剖析
启动MQTT客户端程序时,一般有三个关键模块:Client、Connect、Store。判断程序是否由Node.js直接执行用require.main === module。
在客户端模块中,核心是封装一个MQTT客户端实例。实例底层通过pipe建立管道连接,此管道用于传输数据。
当有数据写入流中,即触发_write方法,消息队列packets中的消息开始被处理。如果队列还有消息,会执行_handlePacket和nextTickWork。nextTickWork通过process.nextTick确保数据不会丢失,使得连接保持活跃。
消息队列的数据不丢失的关键在于process.nextTick机制。
MQTT客户端实例继承了events.EventEmitter方法,所有的异步操作完成后,会发送事件到事件队列,用于后续事件处理。
客户端的基本操作如连接、订阅主题、发送与接收消息,具体如下:
订阅主题时,会调用subscribe方法,该方法先验证topic格式,构造packet并发送至服务器。订阅完成后,会调用回调函数,告知已成功订阅。
发送消息使用publish方法,构造packet,包含主题和消息内容,通过_storePacket或_sendPacket发送。
接收消息时,通过emit和message方法将数据传递给业务代码。数据为buffer数组,需进行序列化处理。
在_sendPacket方法中,使用mqtt-packet生成可传输的buffer,并将packet写入client的stream。stream是初始化MQTT客户端实例时传入的对象,通常包含WebSocket等相关方法。
客户端内部还包含了unsubscribe、resubscribe及end方法,用于取消订阅、重新订阅及断开连接,具体细节不在本文深入讨论。
总体而言,MQTT客户端的实现涉及Node.js的多个知识点,包括异步操作、事件监听、流处理等,构建了一个高效、灵活的消息传输框架。
Python MQTT 异步框架 —— HBMQTT
异步模式解决了CPU速度与IO操作之间的性能瓶颈问题,Python通过引入异步IO特性,使得在遇到IO操作时,程序能够继续执行其他任务,提高效率。Python3.4版本开始标准库中加入了asyncio,并在Python3.5版本中引入了async/await关键字。HBMQTT作为最早的Python MQTT异步框架,实现了MQTT3.1.1协议。
HBMQTT是一个基于Python编写的开源MQTT客户端库,其特性包括支持MQTT3.1.1协议等。通过使用HBMQTT库,可以轻松实现MQTT的发布和订阅功能。
首先,确定使用Python3.6版本进行开发测试,并确保Python版本不低于3.5。使用Pip安装HBMQTT库。连接MQTT服务器时,可以使用EMQ X提供的免费公共MQTT服务器,其接入信息包括服务器地址、端口等。
发布消息的异步函数为MQTTClient类的publish方法。在订阅消息时,使用MQTTClient类中的subscribe方法。实现异步操作的关键在于使用await等待事件的发生,例如接收消息时。
完整代码包含了消息发布和订阅的实现。发布消息代码将三个发送消息函数放入asyncio任务列表中,依次执行。订阅消息代码在接收消息时设置了await,当有消息到达时,CPU会继续执行其他任务,直到消息接收完成。最终程序会等待次消息接收后关闭连接。
运行测试代码,可以看到MQTT客户端成功连接服务器,并成功发布和订阅消息。在MQTT X客户端上,可以查看到HBMQTT客户端发布的消息。通过使用Python异步IO执行消息的发送和接收,可以实现高效、快速的MQTT客户端。
总结,通过使用HBMQTT库与MQTT服务器连接,实现测试客户端与MQTT服务器之间的连接、消息发布和订阅,充分发挥了Python异步IO的优势,提高了MQTT客户端的性能。后续将发布更多关于物联网开发与Python相关的内容,敬请关注。
Paho MqttClient 回调函数使用总结
Eclipse Paho是专为MQTT协议设计的Java客户端库,它基于发布-订阅模型工作,编程时需要为Mqtt客户端实例设置回调函数。这些回调会在后台线程中异步执行,如消息发布成功或接收到订阅主题的消息后。理解每个回调的触发条件至关重要,以避免潜在的错误和bug。
MqttCallback接口提供了几个关键方法,它们在特定条件下会被调用。其中,connectionLost(Throwable cause)方法至关重要。这个方法的实现切勿空置,至少包含一行cause.printStackTrace(),因为任何连接异常,包括messageArrived()或deliveryComplete()引发的异常,都会导致其被调用。cause参数记录了异常堆栈,确保异常信息的可见性,有助于诊断可能的代码问题。
例如,下面的代码中,如果connectionLost()的实现为空,程序在接收到一条订阅消息后就停止接收。这是因为messageArrived()第一次执行时抛出异常,导致客户端主动断开连接。由于connectionLost()的空实现,我们无法察觉到这种断开,使得bug难以察觉。
因此,务必为connectionLost()提供完整的实现,以确保能够追踪并修复messageArrived()或deliveryComplete()中的逻辑错误。这在多线程编程中尤其重要,因为Java程序通常依赖后台线程,对方法运行环境的了解和正确使用是避免bug的关键。