📜  消息队列遥测传输协议(MQTT)的介绍

📅  最后修改于: 2021-08-24 05:07:59             🧑  作者: Mango

MQTT是一种简单,轻量级的消息传递协议,用于在多个设备之间建立通信。它是基于TCP的协议,依赖于发布-订阅模型。该通信协议适合于在具有低带宽和低功率要求的资源受限的设备之间传输数据。因此,此消息传递协议被广泛用于IoT框架中的通信。

发布-订阅模型:
此模型涉及多个客户端彼此交互,而无需在它们之间建立任何直接连接。所有客户仅通过称为经纪人的第三方与其他客户进行通信。

MQTT客户和经纪人:
客户将有关不同主题的消息发布给代理。代理是中央服务器,接收这些消息并根据其主题过滤它们。然后,它将这些消息发送到已订阅这些不同主题的各个客户端。

因此,已订阅特定主题的客户端将接收有关该主题的所有消息。

图–发布-订阅模型

在这里,代理是中央集线器,用于接收消息,过滤消息并将其分发给适当的客户端,这样消息发布者和订阅者都是客户端。

好处 :

  1. 易于扩展–
    此模型不限于客户端之间的一对一通信。尽管发布者客户端发送有关特定主题的单个消息,但是代理将多条消息发送给订阅该主题的所有不同客户端。同样,由多个此类发布者客户端发送的有关多个不同主题的消息将发送给订阅了这些主题的所有多个客户端。

    因此,使用该模型可以进行一对多,多对一以及多对多的通信。同样,由于这种双向通信协议,客户端可以发布数据并同时接收数据。因此,MQTT被认为是双向协议。用于数据传输的默认未加密MQTT端口默认为1883。用于安全传输的加密端口为8883。

  2. 消除不安全的连接–
    在多个设备相互连接的复杂系统中,每个设备不仅必须管理与其他设备的连接,而且还必须确保这些连接的安全性。但是在发布-订阅模型中,代理成为管理所有安全方面的中央服务器。它负责所有连接的客户端的身份验证和授权。
  3. 轻量级沟通–
    数据传输快速,高效且轻巧,因为MQTT消息的代码占用量很小。这些控制消息具有大小为2个字节的固定报头,最大有效载荷消息为256兆字节。

话题 :
在MQTT中,主题是UTF-8字符串,代理用于过滤每个连接的客户端的消息。每个主题都包含一个或多个不同的主题级别。每个主题级别由正斜杠(也称为主题级别分隔符)分隔。主题和级别均区分大小写。

主题示例–

home/kitchen/table 

在这里,“家”,“厨房”和“桌子”是不同级别的主题。

通配符是MQTT中使用的附加功能,可以使主题及其级别更加灵活和用户友好。

MQTT主题包括两种类型的通配符:

  1. 单个级别:“ +”
    用“ +”号表示的单级通配符可以代替主题中的单级通配符。

    例子 –
    如果客户想要有关房屋内所有桌子的信息,它将订阅topic:

    home/+/table 

    因此,可以获取有关此主题的任何有关桌子,厨房,客厅,卧室等的已发布信息。

    图– MQTT中的单级主题

  2. 多级:“#”
    用“#”符号表示的多级通配符可以替换主题中的多级。

    例子 –
    如果客户需要有关厨房,客厅,卧室或底楼任何其他房间内存在的所有对象的信息,它将订阅主题:

    home/groundfloor/# 

    因此,可以获取关于与厨房用品,卧室用品,客厅用品有关的主题的任何信息。在这种情况下,可以获得多达多个级别的信息。

以下程序说明了如何在JavaScript中实现MQTT。

Javascript
//JavaScript Program for publish-subscribe model
/* jshint esversion : 6 */
"use strict";
  
//Importing MQTT
var mqtt = require('mqtt');
  
//Creating an instance of the client
var client = mqtt.connect({clientId: "001"});
  
//Definiting constants
var topic = "home/kitchen/table";
var message = "Table inside the kitchen";
var options = {retain: false, qos: 1};
  
//On successful connection
client.on('connect', function () {
    console.log(" After successful connection: ", client.connected);
    //If client is connected, then publish on the topic
    if (client.connected) {
        console.log(" Publishing on topic: ", topic);
        client.publish(topic, message, options);
    }
});
  
//On connectivity error
client.on('error', function (error) {
    console.log(" Connection error: ", error);
});
  
//On receiving message
client.on('message', function (topic, message) {
    console.log(" Received message: ", message.toString(), "on topic: ", topic);
    client.end();
});
  
function init() {
    //Suscribing to the topic
    console.log("\n Subscribing to topic");
    client.subscribe(topic, {qos: 1});
}
  
//Start of the program
init();