背景
近来公司需要做一个即时通讯工具,选型用MQTT协议来做。于是仔细搜集MQTT相关的了一些资料,并分享出来供大家参考。
MQTT简介
MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)是IBM开发的一个即时通讯协议,它是一种轻量级的、基于代理的“发布/订阅”模式的消息传输协议。其具有协议简洁、小巧、可扩展性强、省流量、省电等优点,而且已经有PHP,JAVA,Python,C,C#,Go等多个语言版本,基本可以使用在任何平台上,几乎可以把所有联网物品和外部连接起来,所以特别适合用来当做物联网的通信协议。
MQTT特点
MQTT协议是为大量计算能力有限,且工作在低带宽、不可靠的网络的远程传感器和控制设备通讯而设计的协议,它具有以下主要的几项特性:
- 使用发布/订阅消息模式,提供一对多的消息发布,解除应用程序耦合;
- 对负载内容屏蔽的消息传输;
- 使用 TCP/IP 提供网络连接;
- 有三种消息发布服务质量:
- “至多一次”,消息发布完全依赖底层 TCP/IP 网络。会发生消息丢失或重复。这一级别可用于如下情况,环境传感器数据,丢失一次读记录无所谓,因为不久后还会有第二次发送。
- “至少一次”,确保消息到达,但消息重复可能会发生。
- “只有一次”,确保消息到达一次。这一级别可用于如下情况,在计费系统中,消息重复或丢失会导致不正确的结果。
- 小型传输,开销很小(固定长度的头部是 2 字节),协议交换最小化,以降低网络流量;
- 使用 Last Will 和 Testament 特性通知有关各方客户端异常中断的机制;
MQTT协议特征
-
消息模型
MQTT是一种基于代理的发布/订阅的消息协议。提供一对多的消息分发,解除应用程序耦合。一个发布者可以对应多个订阅者,当发布者发生变化的时候,他可以将消息一一通知给所有的订阅者。这种模式提供了更大的网络扩展性和更动态的网络拓扑。
-
消息质量
MQTT提供三种质量的服务:- 至多一次,可能会出现丢包的现象。使用在对实时性要求不高的情况。这一级别可应用于如下情景,如环境传感器数据,丢失一次读记录无所谓,因为很快下一次读记录就会产生。
- 至少一次,保证包会到达目的地,但是可能出现重包。
- 正好一次,保证包会到达目的地,且不会出现重包的现象。这一级别可用于如计费系统等场景,在计费系统中,消息丢失或重复可能会导致生成错误的费用。
-
主题名称
主题名称(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库需要提供如下命令:
Connect :当一个TCP/IP套接字在服务器端和客户端连接建立时需要使用的命令。
publish : 是由客户端向服务端发送,告诉服务器端自己感兴趣的Topic。每一个publishMessage 都会与一个Topic的名字联系在一起。
pubRec: 是publish命令的响应,只不过使用了2级QoS协议。它是2级QoS协议的第二条消息
pubRel: 是2级QoS协议的第三条消息
publComp: 是2级QoS协议的第四条消息
subscribe: 允许一个客户端注册自已感兴趣的Topic 名字,发布到这些Topic的消息会以publish Message的形式由服务器端发送给客户端。
unsubscribe: 从客户端到服务器端,退订一个Topic。
Ping: 有客户端向服务器端发送的“are you alive”的消息。
disconnect:断开这个TCP/IP协议。
MQTT服务端和客户端
MQTT协议服务端:https://github.com/mqtt/mqtt.github.io/wiki/servers
MQTT协议类库:https://github.com/mqtt/mqtt.github.io/wiki/libraries
MQTT协议官网:http://mqtt.org/
应用场景
推送
再给大家普及下“推送”这个概念,推送这个词大部分人都会有印象的。比如PC端的推送广告,比如安卓的推送服务,还有一些即时通信软件如微信、易信等也是采用的推送技术。
现在的推送实现的方式已经非常多了,主流的有C2DM服务(Google Cloud Messaging),基于XML协议的通讯协议XMPP协议(Openfire + Spark + Smack), 轻量级的、基于代理的“发布/订阅”模式的消息传输协议MQTT协议,还可以通过嵌入SDK使用第三方提供的推送服务,如百度云推送、极光推送、智游推送、腾讯信鸽等。
推送利用的也是类似于上面提到的代理技术,从而将数据源源不断地推向客户机。笔者对其它协议了解不多所以也不敢多做妄言,但是现在国内很多企业都已经广泛使用MQTT作为Android手机客户端与服务器端推送消息的协议。其中Sohu,Cmstop手机客户端中均有使用到MQTT作为消息推送消息。