MQTT

MQTT 是什么

MQTT (formerly MQ Telemetry Transport) is an ISO standard (ISO/IEC PRF 20922) publish-subscribe-based “lightweight” messaging protocol for use on top of the TCP/IP protocol.

MQTT 是协议轻量级的基于TCP/IP的 发布/订阅 的ISO标准协议。

MQTT For Sensor Networks (MQTT-SN) :
http://mqtt.org/2013/12/mqtt-for-sensor-networks-mqtt-sn

MQTT出现的理由

https://yq.aliyun.com/articles/41705
  万物联网的时代即将到来,物联网也由当初的概念开始进一步落实。随着无线网络技术飞速发展,各种设备都可以连接网络,实现远程控制。例如智能家居最近非常火爆,智能插座、智能LED灯、智能摄像头等。在互联网时代,HTTP协议负责建立网络连接,而到了物联网时代,由于智能硬件的差异,相比互联网终端,硬件配置要低的多,而且智能设备的环境也想多复杂,物联网中的数据传输会面临很多问题,比如在网络不稳定的情况下,如果保证数据的传输没有问题,如何保证数据不被重复发送,连接断开后如何进行重连,而HTTP协议由于太重量级了,不是适合物联网。因此IBM公司为此提出一种轻量级的MQTT协议(MQ Telemetry Transport),适合于低带宽、不可靠连接、嵌入式设备、CPU、内存资源紧张,适用于各种受限的环境。
mqtt 3.1.1已近称为了标准。

谁在使用MQTT

Facebook Messenger. Facebook has used aspects of MQTT in Facebook Messenger.[12] However, it is unclear how much of MQTT is used or for what. Moreover, this is a phone application, not a sensor application.
On October 8, 2015 Amazon Web Services announced Amazon IoT based on MQTT

国内创业公司:云吧。通过MQTT的sub/pub模式,实现双向通信。官网有许多例子、在线聊天、弹幕系统、只能空调等。github上还有一些示例程序可以学习。

http://yunba.io/usercases/air-conditioner/

使用MQTT的一般架构

MQTT协议特征

消息模型

这里写图片描述

消息质量

MQTT提供三种质量的服务,对重传的控制:

1)至多一次,可能会出现丢包的现象。使用在对实时性要求不高的情况。这一级别可应用于如下情景,如环境传感器数据,丢失一次读记录无所谓,因为很快下一次读记录就会产生。

2)至少一次,保证包会到达目的地,但是可能出现重包。

3)正好一次,保证包会到达目的地,且不会出现重包的现象。这一级别可用于如计费系统等场景,在计费系统中,消息丢失或重复可能会导致生成错误的费用。

主题名称

  主题名称(Topic name)用来标识已发布消息的信息的渠道。订阅者用它来确定接收到所关心的信息。它是一个分层的结构,用斜线“/”作为分隔符。有两种通配符可以在主题发布、订阅时使用:“#”和“+”。前者可以通配多层结构,而后者只能通配一层结构。例如一个topic : “a/b/c”,则“a/+/c”和“a/#”都可以和它相等。发布不支持模糊匹配,必须是确定的主题。

遗属

  当一个客户端断开连接的时候,它希望服务端可以发送它指定的消息。该消息和普通消息的结构相同。通过设置该位并填入和信息相关的内容即可。

消息类型

Reserved     0   保留
 Connect     1   客户端到服务端的连接请求
 ConnACK     2   服务端对连接请求的响应
 Publish     3   发布消息
 puback      4   对发布消息的回应


 pubRec      5   收到发布消息(保证传输part1)
 pubRel      6   释放发布消息(保证传输part2)
 pubComp     7   完成发布消息(保证传输part3)
 subscribe   8   客户端订阅请求
 subBack     9   订阅请求的回应


 unsubscribe 10      停止订阅请求
 unsubBack   11      停止订阅请求响应
 pingReq     12      Ping请求(保持连接)
 pingResp    13      Ping响应
 disconnect  14      客户端正在断开
 reserved    15      保留

可选的MQTT server

列表: https://github.com/mqtt/mqtt.github.io/wiki/servers

mosquitto

http://mosquitto.org/

mosquitto使用C语言开发,在linux下底层使用poll作为IO multiplexing

moquette

https://github.com/andsel/moquette

基于Netty的MQTT server

使用mosquitto演示mqtt协议的使用

http://blog.csdn.net/zhu_tianwei/article/details/42914949

MQTT Client

MQTT Client可以作为发布者/订阅者,验证功能。
根据百度云平台的文档,发现了MQTTfx,功能比较全面了。Java写的,就是觉得启动慢了点。

MQTT 协议分析

http://public.dhe.ibm.com/software/dw/webservices/ws-mqtt/mqtt-v3r1.html
http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/errata01/os/mqtt-v3.1.1-errata01-os-complete.html
https://www.gitbook.com/book/mcxiaoke/mqtt-cn/details
http://www.cnblogs.com/Free-Thinker/p/5559816.html

MQTT是一个客户端服务端架构的发布/订阅模式的消息传输协议。它的设计思想是轻巧、开放、简单、规范,易于实现。这些特点使得它对很多场景来说都是很好的选择,特别是对于受限的环境如机器与机器的通信(M2M)以及物联网环境(IoT)。

分析版本 3.1.1(已经成为了一个标准了)

包格式

http://public.dhe.ibm.com/software/dw/webservices/ws-mqtt/mqtt-v3r1.html#msg-format

包含三部分:

固定头(fixed header) | 可变头(variable header) | 载荷(payload)

可变头和载荷只在某些类型的包中出现。

共有16中类型的包。其中的数据都是big-endian(网络字节序)。

固定头的remain length至少为一个字节,最多4个字节。它采用变成编码表示 可变头+载荷的长度。使用每个字节的最高位表示是否还有后续字节。

所以最大长度为: 268 435 455 (256 MB)。

可变头:The protocol name is present in the variable header of a MQTT CONNECT message. This field is a UTF-encoded string that represents the protocol name MQIsdp, capitalized as shown.

string

In MQTT, strings are prefixed with two bytes to denote the length, as shown in the table below.

MQTT中的string使用前两个字节表示string的长度。

建立连接

CONNECT 包

http://public.dhe.ibm.com/software/dw/webservices/ws-mqtt/mqtt-v3r1.html#connect

该包是在已经建立了TCP连接之后,由client 发送给 server。

可变头是12字节,结构见上面引文。

CONNECT包的payload开始部分必须会包含一个Client Identifier,它必须是一个UTF-8编码的字符串。长度为1~23字节,每个字符必须是数组或字符[a-zA-Z]:0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ中。如果长度超过23字节,Server应该在返回的CONNACK的return code设置为2,即Identifier Rejected.(Client ID不合法)

此外CONNECT包的payload部分可以包含will topicwill messageusernamepassword

Keep Alive
保持连接(Keep Alive)是一个以秒为单位的时间间隔,表示为一个16位的字,它是指在客户端传输完成一个控制报文的时刻到发送下一个报文的时刻,两者之间允许空闲的最大时间间隔。客户端负责保证控制报文发送的时间间隔不超过保持连接的值。如果没有任何其它的控制报文可以发送,客户端必须发送一个PINGREQ报文

CONNACK 包

http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/errata01/os/mqtt-v3.1.1-errata01-os-complete.html#_Toc442180846

该包由 server 发送给 client,作为client发送CONNECT包的response。

订阅

SUBSCRIBE 包

http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/errata01/os/mqtt-v3.1.1-errata01-os-complete.html#_Toc442180876

client使用该包来订阅一个或多个topic,所以是由client发送给server的包。

该包的payload包含了一个topic filter的列表,表示想要订阅哪些topic。

The payload of a SUBSCRIBE Packet contains a list of Topic Filters indicating the Topics to which the Client wants to subscribe.

SUBACK 包

http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/errata01/os/mqtt-v3.1.1-errata01-os-complete.html#_Toc442180881

协议分析总结

MQTT实际上是在TCP基础上的分包。(想起muduo中讲到了TCP分包)

MQTT Security

这一部分只是一份建议,并不是标准的一部分。在TCP 8883端口上使用TLS保护。

MQTT solutions are often deployed in hostile communication environments. In such cases, implementations will often need to provide mechanisms for:

  • Authentication of users and devices
  • Authorization of access to Server resources
  • Integrity of MQTT Control Packets and application data contained therein
  • Privacy of MQTT Control Packets and application data contained therein

使用Username/Password认证

配置文件mosquitto.conf:

password_file /etc/mosquitto/passwd
allow_anonymous false

password_file 使用mosquitto_passwd管理,密码部分不是明文而是hash。
配置好就可以用来认证了。发布或订阅都要加上用户名和密码 -u username -P password

不过,没有使用TLS的话用户名和密码都是明文传输的。所以需要使用TLS对通信进行加密。

使用TLS加密

http://dataguild.org/?p=6866

MQTT-SN : MQTT For Sensor Networks (MQTT-SN) :

http://modelbasedtesting.co.uk/?p=44
http://mqtt.org/2013/12/mqtt-for-sensor-networks-mqtt-sn
http://git.eclipse.org/c/mosquitto/org.eclipse.mosquitto.rsmb.git/
http://www.blogjava.net/yongboy/archive/2015/01.html 推荐

MQTT-SN可以运行在不同的无线协议上,只要可以满足MQTT-SN 所定义即可:支持双向数据传输和网关即可,MQTT-SN完全可以运行在其上面。
这里写图片描述
MQTT-SN可以在ZigBee、Bluetooth、RF、UDP、6loWPAN等底层协议层面运行。

这里写图片描述

从架构图中看到,Zigbee终端节点与中控节点之间使用MQTT-SN,而中控与MQTTbroker之间采用MQTT。

云平台

Baidu云

介绍: https://cloud.baidu.com/solution/iot.html
WebSocket : http://websocketshow.fc.bdysite.com/

现在免费,使用了一些感觉还可以。支持MQTT协议;有websocket管理控制台(可以通过浏览器模拟发布者/订阅者的行为,方便调试);设备与某个身份绑定,用于认证(也就是MQTT CONNECT包中的Username/Password);TLS加密,身份认证必须使用TLS保护,否则是明文传输;

没有AWS IoT的Shadow功能:某个客户端C1订阅了某个主题T1,但是与MQTT服务器断开了连接,这时候有某个发布者P1发布了主题T1的消息M,那么当C1重新连接上MQTT服务器时,C1应不应该收到消息M呢?个人认为应该收到。AWS IoT提出了Shadow设备来解决了这个问题,当客户端断线重连时,也会收到该主题之前的消息。

AWS IoT (亚马逊)

阿里巴巴

其他引文

http://blog.csdn.net/zhu_tianwei/article/details/42914949

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值