为何 MQTT 是最适合物联网的网络协议php
物联网 (IoT) 设备必须链接互联网。经过链接到互联网,设备就能相互协做,以及与后端服务协同工做。互联网的基础网络协议是 TCP/IP。MQTT(消息队列遥测传输) 是基于 TCP/IP 协议栈而构建的,已成为 IoT 通讯的标准。数据库
MQTT 最初由 IBM 于上世纪 90 年代晚期发明和开发。它最初的用途是将石油管道上的传感器与卫星相连接。顾名思义,它是一种支持在各方之间异步通讯的消息协议。异步消息协议在空间和时间上将消息发送者与接收者分离,所以能够在不可靠的网络环境中进行扩展。虽然叫作消息队列遥测传输,但它与消息队列毫无关系,而是使用了一个发布和订阅的模型。在 2014 年底,它正式成为了一种 OASIS 开放标准,并且在一些流行的编程语言中受到支持(经过使用多种开源实现)。编程
MQTT 是一种轻量级的、灵活的网络协议,致力于为 IoT 开发人员实现适当的平衡:后端
为了了解为何 MQTT 如此适合 IoT 开发人员,咱们首先来分析一下为何其余流行网络协议未在 IoT 中获得成功应用。浏览器
大多数开发人员已经熟悉 HTTP Web 服务。那么为何不让 IoT 设备链接到 Web 服务?设备可采用 HTTP 请求的形式发送其数据,并采用 HTTP 响应的形式从系统接收更新。这种请求和响应模式存在一些严重的局限性:服务器
出于上述缘由,大部分高性能、可扩展的系统都使用异步消息总线来进行内部数据交换,而不使用 Web 服务。事实上,企业中间件系统中使用的最流行的消息协议被称为 AMQP(高级消息排队协议)。可是,在高性能环境中,计算能力和网络延迟一般不是问题。AMQP 致力于在企业应用程序中实现可靠性和互操做性。它拥有庞大的特性集,但不适合资源受限的 IoT 应用程序。网络
除了 AMQP 以外,还有其余流行的消息协议。例如,XMPP(Extensible Messaging and Presence Protocol,可扩展消息和状态协议)是一种对等即时消息 (IM) 协议。它高度依赖于支持 IM 用例的特性,好比存在状态和介质链接。与 MQTT 相比,它在设备和网络上须要的资源都要多得多。session
那么,MQTT 为何如此轻量且灵活?MQTT 协议的一个关键特性是发布和订阅模型。与全部消息协议同样,它将数据的发布者与使用者分离。eclipse
MQTT 协议在网络中定义了两种实体类型:一个消息代理和一些客户端。代理是一个服务器,它从客户端接收全部消息,而后将这些消息路由到相关的目标客户端。客户端是可以与代理交互来发送和接收消息的任何事物。客户端能够是现场的 IoT 传感器,或者是数据中心内处理 IoT 数据的应用程序。
由于 MQTT 消息是按主题进行组织的,因此应用程序开发人员能灵活地指定某些客户端只能与某些消息交互。例如,传感器将在 “sensor_data” 主题范围内发布读数,并订阅 “config_change” 主题。将传感器数据保存到后端数据库中的数据处理应用程序会订阅 “sensor_data” 主题。管理控制台应用程序能接收系统管理员的命令来调整传感器的配置,好比灵敏度和采样频率,并将这些更改发布到 “config_change” 主题。(参阅图 1。)
同时,MQTT 是轻量级的。它有一个用来指定消息类型的简单标头,有一个基于文本的主题,还有一个任意的二进制有效负载。应用程序可对有效负载采用任何数据格式,好比 JSON、XML、加密二进制或 Base64,只要目标客户端可以解析该有效负载。
开始进行 MQTT 开发的最简单工具是 Python mosquitto 模块,该模块包含在 Eclipse Paho 项目 中,提供了多种编程语言格式的 MQTT SDK 和库。它包含一个能在本地计算机上运行的 MQTT 代理,还包含使用消息与代理交互的命令行工具。能够从 mosquitto 网站 下载并安装 mosquitto 模块。
mosquitto 命令在本地计算机上运行 MQTT 代理。也可使用 -d 选项在后台运行它。
$ mosquitto -d
接下来,在另外一个终端窗口中,可使用 mosquitto_sub 命令链接到本地代理并订阅一个主题。运行该命令后,它将等待从订阅的主题接收消息,并打印出全部消息。
$ mosquitto_sub -t "dw/demo"
在另外一个终端窗口中,可使用 mosquitto_pub 命令链接到本地代理,而后向一个主题发布一条消息。
$ mosquitto_pub -t "dw/demo" -m "hello world!"
如今,运行 mosquitto_sub 的终端会在屏幕上打印出 “hello world!”。您刚才使用 MQTT 代理发送并接收了一条消息!
固然,在生产系统中,不能使用本地计算机做为代理。相反,可使用 IBM Bluemix Internet of Things Platform 服务,这是一种可靠的按需服务,功能与 MQTT 代理相似。要进一步了解这个 Bluemix 服务如何集成并使用 MQTT 做为与设备和应用程序通讯的协议,请参阅 该服务的文档。)
IBM Bluemix Internet of Things Platform 服务 的工做原理以下。
使用远程 MQTT 代理时,须要将代理的主机名和身份验证凭证传递给 mosquitto_sub 和 mosquitto_pub 命令。例如,下面的命令使用了 Bluemix 提供的用户名和密码,订阅咱们的 Internet of Things Platform 服务上的 demo 主题:
$ mosquitto_sub -t "demo" -h host.iotp.mqtt.bluemix.com -u username -P password
有关使用 mosquitto 工具的更多选择,以及如何使用 mosquitto API 建立本身的 MQTT 客户端应用程序,请参阅 mosquitto 网站 上的文档。
有了必要的工具后,让咱们来更深刻地研究 MQTT 协议。
MQTT 是一种链接协议,它指定了如何组织数据字节并经过 TCP/IP 网络传输它们。但实际上,开发人员并不须要了解这个链接协议。咱们只须要知道,每条消息有一个命令和数据有效负载。该命令定义消息类型(例如 CONNECT 消息或 SUBSCRIBE 消息)。全部 MQTT 库和工具都提供了直接处理这些消息的简单方法,并能自动填充一些必需的字段,好比消息和客户端 ID。
首先,客户端发送一条 CONNECT 消息来链接代理。CONNECT 消息要求创建从客户端到代理的链接。CONNECT 消息包含如下内容参数。
参数 | 说明 |
cleanSession | 此标志指定链接是不是持久性的。持久会话会将全部订阅和可能丢失的消息(具体取决于 QoS) 都存储在代理中。(请参阅 表 3 获取 QoS 的描述。) |
username | 代理的身份验证和受权凭证。 |
password | 代理的身份验证和受权凭证。 |
lastWillTopic | 链接意外中断时,代理会自动向某个主题发送一条 “last will” 消息。 |
lastWillQos | “last will” 消息的 QoS。(请参阅 表 3 来查看 QoS 的描述。) |
lastWillMessage | “last will” 消息自己。 |
keepAlive | 这是客户端经过 ping 代理来保持链接有效所需的时间间隔。 |
客户端收到来自代理的一条 CONNACK 消息。CONNACK 消息包含如下内容参数。
参数 | 说明 |
sessionPresent | 此参数代表链接是否已有一个持久会话。也就是说,链接已订阅了主题,并且会接收丢失的消息。 |
returnCode | 0 表示成功。其余值指出了失败的缘由。 |
创建链接后,客户端而后会向代理发送一条或多条 SUBSCRIBE 消息,代表它会从代理接收针对某些主题的消息。消息能够包含一个或多个重复的参数。如表 3。
参数 | 说明 |
qos | qos(服务质量或 QoS)标志代表此主题范围内的消息传送到客户端所需的一致程度。
|
topic | 要订阅的主题。一个主题能够有多个级别,级别之间用斜杠字符分隔。例如,“dw/demo” 和 “ibm/bluemix/mqtt” 是有效的主题。 |
客户端成功订阅某个主题后,代理会返回一条 SUBACK 消息,其中包含一个或多个 returnCode 参数。
参数 | 说明 |
returnCode | SUBCRIBE 命令中的每一个主题都有一个返回代码。返回值以下所示。
|
与 SUBSCRIBE 消息对应,客户端也能够经过 UNSUBSCRIBE 消息取消订阅一个或多个主题。
参数 | 说明 |
topic | 此参数可重复用于多个主题。 |
客户端可向代理发送 PUBLISH 消息。该消息包含一个主题和数据有效负载。代理而后将消息转发给全部订阅该主题的客户端。
参数 | 说明 |
topicName | 发布的消息的相关主题。 |
qos | 消息传递的服务质量水平。(请参阅 表 3 来查看 QoS 的描述。) |
retainFlag | 此标志代表代理是否保留该消息做为针对此主题的最后一条已知消息。 |
payload | 消息中的实际数据。它能够是文本字符串或二进制大对象数据。 |
MQTT 的优点在于它的简单性。在可使用的主题类型或消息有效负载上没有任何限制。这支持一些有趣的用例。例如,请考虑如下问题:
如何使用 MQTT 发送 1-1 消息?双方能够协商使用一个特定于它们的主题。例如,主题名称能够包含两个客户端的 ID,以确保它的惟一性。
客户端如何传输它的存在状态?系统能够为 “presence” 主题协商一个命名约定。例如,“presence/client-id” 主题能够拥有客户端的存在状态信息。当客户端创建链接时,将该消息被设置为 true,在断开链接时,该消息被设置为 false。客户端也能够将一条 last will 消息设置为 false,以便在链接丢失时设置该消息。代理能够保留该消息,让新客户端可以读取该主题并找到存在状态。
如何保护通讯?客户端与代理的链接能够采用加密 TLS 链接,以保护传输中的数据。此外,由于 MQTT 协议对有效负载数据格式没有任何限制,因此系统能够协商一种加密方法和密钥更新机制。在这以后,有效负载中的全部内容能够是实际 JSON 或 XML 消息的加密二进制数据。
本文从技术角度介绍了 MQTT 协议。您了解了 MQTT 是什么,MQTT 为何适合 IoT 应用程序,以及如何开始开发使用 MQTT 的应用程序。
【来源】