【MQTT】1. MQTT协议和MQTT客户端库介绍

MQTT简介

MQTT(全名为Message Queuing Telemetry Transport 中文翻译过来就是遥测传输协议) 是一种基于TCP/IP协议上传输的轻量级通信协议。其主要提供订阅/发布模式,更为简约、轻量,易于使用,针对受限环境(带宽低、网络延迟高、网络通信不稳定),属于物联网(Internet of Thing)的一个传输协议。设计思想是开放、简单、轻量、易于实现。

MQTT协议是基于客户端-服务器模型,在协议中主要有三种身份:发布者(Publisher)、服务器(Broker) 以及订阅者(Subscriber)。并且消息发布者同时也可以是订阅者 。MQTT 消息的发布者和订阅者都是客户端,服务器只是作为一个中转的存在,将发布者发布的消息进行转发给所有订阅该主题的订阅者。

参见:

MQTT物联网通讯的标准(官网)

MQTT协议

MQTT Version 3.1.1

MQTT Version 5.0

MQTT 3.1.1 vs. 5.0

基于C语言的客户端库

参见:MQTT软件介绍 下的 Client libraries ==> C

Qos

有三种消息发布服务质量(QoS):

  • "至多一次"(QoS==0),消息发布完全依赖底层 TCP/IP 网络。会发生消息丢失或重复。这一级别可用于如下情况,环境传感器数据,丢失一次读记录无所谓,因为不久后还会有第二次发送。

  • "至少一次"(QoS==1),确保消息到达,但消息重复可能会发生。

  • "只有一次"(QoS==2),确保消息到达一次。这一级别可用于如下情况,在计费系统中,消息重复或丢失会导致不正确的结果。小型传输,开销很小(固定长度的头部是 2 字节),协议交换最小化,以降低网络流量。

参见:Paho MQTT: Quality of service

Topic

Topic的分割符与通配符

  • 分割符"/":为方便主题管理与扩展,mqtt的主题是有路径的,以"/"分割

  • 通配符"#":表示层次结构的完整子树,比如SENSOR/#,因此"#"只能为最后一个字符

  • 通配符"+":标识层次结构的单个级别,用于分隔符之间,比如SENSOR/+/TEMP

参见: Paho MQTT: Topic

Mosquitto和Eclipse Paho

Mosquitto 是MQTT协议标准的一种开源实现,其具体的操作方式,请参考http://mosquitto.org/man/mosquitto-8.html

Eclipse Paho是Eclipse 提供的一个访问MQTT服务器的一种开源客户端库

参见:MQTT,mosquitto,Eclipse Paho

Paho MQTT客户端的版本比较

使用Mosquitto搭建一个MQTT代理服务器

Mosquitto supports MQTT v5.0, v3.1.1, and v3.1

1. 安装

//引入库 
sudo apt-add-repository ppa:mosquitto-dev/mosquitto-ppa 
//安装mosquitto 
sudo apt-get install mosquitto 
//安装客户端 
sudo apt-get install mosquitto-clients

2. 添加配置文件

sudo vi /etc/mosquitto/conf.d/myconfig.conf

粘入下面这些配置

#添加监听端口(很重要,否则只能本机访问) 
listener 1883 
#------------------------------------------- 
# 关闭匿名访问,客户端必须使用用户名 
allow_anonymous false 

#指定 用户名-密码 文件 
password_file /etc/mosquitto/pwfile.txt 
#--------------------------------------------

3. 添加账户和密码

sudo mosquitto_passwd -c /etc/mosquitto/pwfile.txt 用户名

//例如

sudo mosquitto_passwd -c /etc/mosquitto/pwfile.txt zhang

回车后需要连续两次输入用户密码

4. 服务控制

//配置完参数之后要重启一下服务,否则不会生效 

//启动mqtt服务 
sudo service mosquitto start 

//停止服务 
sudo service mosquitto stop 

//查看服务器状态 
sudo service mosquitto status

5. 创建订阅和推送

//创建订阅 mosquitto_sub -h IP -p 端口(空的话默认1883) -t "监听的Topic" -u 用户名 -P 密码 -i 客户端ID信息 
mosquitto_sub -h 192.168.1.216 -t "zsy001/#" -u zhang -P zhang123 -i "client1" 

//推送消息 
mosquitto_pub -h 192.168.1.216 -t "zsy001/testTopic" -u zhang -P zhang123 -m "Hello MQTT from mosquitto-clients" 

详细参见 
mosquitto_sub --help 
mosquitto_pub --help

6. win环境下使用MQTTX连接

MQTT X: Cross-platform MQTT 5.0 Desktop Client

参见:Ubuntu搭建mosquitto服务器(MQTT服务器)

Paho MQTT C库(最终是要使用这个)

Eclipse Paho Downloads

Lib库如下

paho-mqtt3a :a异步API接口的库,API函数以MQTTAsync开头,API函数定义在MQTTAsync.h

paho-mqtt3as :as表示的是异步+加密(asynchronous+OpenSSL)这个库默认带有TLS加密功能

paho-mqtt3c :c同步API接口的库,API函数以MQTTClient开头,API函数定义在MQTTClient.h

paho-mqtt3cs :cs同步API接口的库,带有TLS加密功能同时也需要openssl库支持

同步模式和异步模式参见后面的介绍

编译paho

paho库是使用cmake编译的; 
//进入库文件所在目录下,创建生成Makefile文件 
cmake . 
2. 编译成静态库 -DPAHO_BUILD_STATIC=TRUE 
3. 生成支持OpenSSL的库 -DPAHO_WITH_SSL=TRUE 
例如: 编译成静态库 cmake . -DPAHO_BUILD_STATIC=TRUE -DPAHO_WITH_SSL=TRUE 
生成的库文件
zsy@ubuntu:~/share/mqtt/paho.mqtt.c-1.3.9$ find -name *.a 
./src/libpaho-mqtt3a.a 
./src/libpaho-mqtt3as.a 
./src/libpaho-mqtt3cs.a 
./src/libpaho-mqtt3c.a 
zsy@ubuntu:~/share/mqtt/paho.mqtt.c-1.3.9$ 
zsy@ubuntu:~/share/mqtt/paho.mqtt.c-1.3.9$ 
zsy@ubuntu:~/share/mqtt/paho.mqtt.c-1.3.9$ find -name *.so 
./src/libpaho-mqtt3as.so 
./src/libpaho-mqtt3cs.so 
./src/libpaho-mqtt3a.so 
./src/libpaho-mqtt3c.so 
zsy@ubuntu:~/share/mqtt/paho.mqtt.c-1.3.9$ 

交叉编译(需要指定openssl的编译生成文件) 
cmake . -DCMAKE_C_COMPILER=mips-linux-uclibc-gnu-gcc -DOPENSSL_SEARCH_PATH=/xxxx/mips472_ssl2 -DOPENSSL_INCLUDE_DIR=/xxxx/mips472_ssl2/include/ -DOPENSSL_SSL_LIBRARY=/xxxx/mips472_ssl2/lib/libssl.a -DOPENSSL_CRYPTO_LIBRARY=/xxxx/mips472_ssl2/lib/libcrypto.a -DPAHO_BUILD_STATIC=TRUE -DPAHO_WITH_SSL=TRUE

同步模式和异步模式

同步模式(MQTTClient)

同步API目的是更加简单、更加有用的。为了达到这个目的,部分操作将被阻塞,直到这个操作完成,这样程序的框架更加简单。

Paho MQTTClient 官方文档

同步发布例子:https://www.eclipse.org/paho/files/mqttdoc/MQTTClient/html/pubsync.html

异步模式(MQTTAsync)

异步模式中只有一个调用会被阻塞——waitForCompletion。异步模式都是通过回调函数返回结果,其特点是多线程,非阻塞。这样更适合那些不是控制主线程的应用,如界面编程的开发

Paho MQTTAsync 官方文档

MQTTClient同步和异步模式并存

虽然paho.mqtt.c存在两种模式API接口,一个是异步的MQTTAsync,另一个是同步的MQTTClient。但这里说的同步和异步并不是绝对的。在MQTTClient接口中,应用程序依然可以通过MQTTClient_setCallbacks()接口函数将一些操作设置为异步模式,比如失去连接,接收订阅消息和接收发布消息交付的结果。

在MQTTClient的同步模式中,客户端应用代码运行在一个单个的线程中,消息通过MQTTClient_publish() 和MQTTClient_publishMessage() 两个函数进行发布。可以通过MQTTClient_waitForCompletion() 函数去确定Qos1和Qos2类型的消息是否被成功的交付到服务器。 可以使用MQTTClient_receive()函数进行同步模式下接收一个消息。为了可以处理一些需要回复的应答和保持网络连接的MQTT "ping"消息,应用程序必须以一定的频率去调用MQTTClient_receive() 或者 MQTTClient_yield() 函数。

在MQTTClient的异步模式中,客户端运行在多个线程上。主程序可以向同步模式一样调用客户端的库函数进行,发布和订阅消息,但是对于一些握手和网络连接维护的操作在后台进行。状态的通知和被接收的消息,通过由MQTTClient_setCallbacks()(包括MQTTClient_messageArrived(), MQTTClient_connectionLost() 和MQTTClient_deliveryComplete())注册的回调函数提供。这些API不是线程安全的,不能在没有同步机制的多线程下面进行调用。对于线程安全的函数可以使用MQTTAsync中的API,然而,这个 API 不是线程安全的——不可能在没有同步的情况下从多个线程调用它。您可以为此使用 MQTTAsync API。

详细参见:Paho MQTT C Client Library: Asynchronous vs synchronous client applications

异步发布例子: Paho MQTT C Client Library: Asynchronous publication example

异步订阅例子:Paho MQTT C Client Library:Asynchronous subscription example

Paho嵌入式库(这个库的mqtts需要自己添加)

“完整的”Paho MQTT C 客户端库是在考虑 Linux 和 Windows 的情况下编写的。它假定存在用于网络(套接字)、线程和内存分配的 Posix 或 Windows 库。嵌入式库旨在具有以下特征:

  • 使用非常有限的资源 - 挑选所需的组件

  • 不依赖于任何特定的网络、线程或内存管理库

  • 最低级别的 ANSI 标准 C 以实现最大的可移植性

  • C 和/或 C++ 中的可选更高层。

嵌入式Paho库是分为 MQTTClient;MQTTClient-C;MQTTPacket

注意这个嵌入式版本的库支持v3.1.1, v3.1, 不支持v5.0 MQTT协议

MQTTPacket

这是最底层的库,最简单,最小,但最难使用。它只是处理 MQTT 数据包的序列化和反序列化。序列化意味着获取应用程序数据并将其转换为准备好通过网络发送的形式。反序列化意味着从网络中读取数据并提取数据。

MQTTClient

基于C++实现的MQTT客户端,但它仍然避免了动态内存分配,并且具有用于操作系统和网络相关功能的可替换类,也避免使用 STL。它基于并需要 MQTTPacket

MQTTClient-C

基于C语言实现, 也是基于并需要 MQTTPacket

参见: Paho Embedded MQTT C/C++ Client Libraries

编译Paho嵌入式库

mkdir build.paho 
cd build.paho 
cmake .. make 

交叉编译 
cmake .. -DCMAKE_C_COMPILER=/home/zsy/ipc_build/mips-gcc540-glibc222-64bit-r3.3.0/bin/mips-linux-uclibc-gnu-gcc 

增加测试程序demo,编译后运行: 
./demo --host 192.168.50.115 --topic celink/mqtt/zhang --username zhang --password zhang123 --clientid demo1

LwIP的MQTT客户端

LwIP的MQTT客户端是在LwIP协议栈中的mqtt模块,也是支持简单的MQTT连接,订阅,发布等功能

lwIP: MQTT 

client

lwIP - A Lightweight TCP/IP stack - Summary

这个是网上基于LwIP移植出来的MQTT模块,其MQTT本身的底层实现也是基于eclipse paho接口

https://gitlab.com/rts_nepal/embedded/lwIP_mbedtls_mqtt_c/-/tree/master/

涂鸦平台的MQTT

TuyaLink 协议是涂鸦 IoT 开发平台面向物联网开发领域设计的一种数据交换规范,数据格式为JSON,主要用于设备端和涂鸦 IoT 开发平台的双向通信,更便捷地实现了设备端和平台之间的业务数据交互。

  1. 消息服务质量 QoS(Quality of Service):发布消息的服务质量,即:保证消息传递的次数。支持 QoS 0 和 QoS 1,但是不支持 QoS 2

  2. MQTT 版本主要有三个,分别是 MQTT 3.1、MQTT 3.1.1 和 MQTT 5。目前,物联网环境中使用最多的是 MQTT 3.1.1 协议。涂鸦平台支持 MQTT 3.1.1,暂不支持 MQTT 5

  3. 一机一密:预先为每个设备烧录其唯一的设备证书(即 ProductIDDeviceIDDeviceSecret)。当设备与云平台建立连接时,云平台对其携带的设备证书信息进行加密计算,最后使用 username/password 的方式认证;计算规则参见:一机一密认证

  4. 主题概览:MQTT主题(Topic)概览

  5. 涂鸦云端通过物模型描述设备的功能定义,将设备功能抽象为属性、动作与事件。

参见: Tuya MQTT 标准协议

SDK:C Tuya IoT Core SDK

涂鸦IOT平台的MQTT是基 AWS的CoreMqtt库 CoreMqtt 库 - FreeRTOS

阿里云平台的MQTT

  1. 支持QoS 0、QoS 1,不支持QoS 2

  2. 协议支持v5.0、v3.1.1和v3.1

  3. TCP通道TLS直连模式:安全级别高

  • 支持TLS协议1.0、1.1和1.2版本,设备端LinkSDK已配置V1.2版本的TLS协议,无需自行配置

  • TCP直连模式,并使用芯片级加密(ID²硬件集成):安全级别高。

  • TCP直连模式(数据不加密):不安全,功能即将下线。

  1. 一机一密,计算MQTT签名参数 - 阿里云物联网平台 

  2. 微消息队列MQTT版 是阿里云推出的一款面向移动互联网以及物联网领域的轻量级消息中间件,基于Eclipse Paho接口

参见:MQTT协议规范 - 阿里云物联网平台

  • 45
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值