当前位置:   article > 正文

MQTT协议及使用_mqttendpoint

mqttendpoint

前言:最近公司有一个项目要用到MQTT,这就涉及到了我的知识盲区了,知识有限的我,立即查资料看文档学习一下,然后将学习心得整理记录一下。

MQTT是什么

MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)借用 官方 的话:轻量级物联网消息推送协议。从这句话中就可以提炼出几个重要的信息:

  • 轻量级
  • 用于物联网
  • 是一种传输协议

既然是一种轻量级的传输协议,那么必然是容易上手的,简单的。他是IBM开发的一个即时通讯协议,它是一种轻量级的、基于代理的“发布/订阅”模式的消息传输协议。与HTTP之类的协议相比,MQTT在通过网络传输数据时表现出众。
目前已经有PHP,JAVA,Python,C,C#,Go,JavaScript等多个语言版本,基本可以使用在任何平台上。当前我做的项目就是基于JavaScript版本支持的MQTT。

MQTT的历史

在官网中并没有提及MQTT的来历,也不知道是谁给创造出来的,既然要学习MQTT,最开始肯定是要了解一下其历史的,那么继续扒一扒MQTT的跟脚。

IBM公司的 安迪·斯坦福-克拉克 及 Cirrus Link公司的 阿兰·尼普1999年 撰写了该协议的第一个版本

上面这段是我再百度百科中找到的,这是地址

其应用范围及场景主要有:

MQTT的基本原理

在MQTT协议通讯中,有两个最为重要的角色。它们分别是服务端客户端

  • 服务端

    MQTT服务端其实就是一台服务器。它是MQTT信息传输的枢纽,负责将MQTT客户端发送来的信息传递给MQTT客户端。MQTT服务端还负责管理MQTT客户端。确保客户端之间的通讯顺畅,保证MQTT消息得以正确接收和准确投递。

  • 客户端

    MQTT客户端可以向服务端发布信息,也可以从服务端收取信息。我们把客户端发送信息的行为成为发布信息。而客户端要想从服务端收取信息,则首先要向服务端订阅信息。

    例:
    “订阅” 信息这一操作很像我们在视频网站订阅某一部电视剧。当这部电视剧上新后,视频网站会向订阅了该剧的用户发送信息,告诉他们有新剧上线了。

  • 主题

    刚刚我们在讲解MQTT客户端订阅信息时,使用了用户在视频网站订阅电视剧这个例子。在MQTT通讯中,客户端所订阅的肯定不是一部部电视剧,而是一个个主题。上面例子中的电视剧名称其实就是这里所说的主题,MQTT服务端在管理MQTT信息通讯时,就是使用“主题”来控制的。

  • 发布与订阅

    从以上实例我们可以看到,MQTT通讯的核心枢纽是MQTT服务端。有了服务端对MQTT信息的接收、储存、处理和发送,客户端在发布和订阅信息时,可以相互独立,且在空间上可以分离,时间上可以异步。这里所说的相互独立、空间和时间分离具体指的是什么呢?

MQTT的特点

  • 开放消息协议,简单且容易在客户端实现

    因此,MQTT成为了当今世界上最受欢迎的物联网协议。它已广泛应用于车联网、智能家居、即时聊天应用和工业互联网等领域。目前通过MQTT协议连接的设备已经过亿,这些都得益于MQTT 协议为设备提供了稳定、可靠、易用的通信基础。

  • 发布订阅模式,一对多消息发布
    在这里插入图片描述
    图示这里只有一台客户端客户端可以发布消息,但并不是最多只能一台客户端进行发布消息,而是所有的客户端都可以发布消息,所以这里就要具体分析具体处理,根据自身业务需求来定。

  • 基于TCP/IP网络连接,提供有序,无损,双向连接。

  • 1字节固定报头,2字节心跳报文,最小化传输开销和协议交换,有效减少网络流量。

  • 消息QoS支持,可靠传输保证

MQTT都有哪些功能

  • 准备工作

    // 下载依赖包并引入,不论是React 或者 Vue 都可以正常跑起来
    import MQTT from 'mqtt';
    
    // 成功连接MQTT服务器后返回的客户端信息
    let client = {};
     	
    // 连接MQTT服务端的基础配置
    const connection = {
       host: 'MQTT服务器IP地址',
       port: '端口号',
       endpoint: '/mqtt', // 默认"/mqtt",string
       clean: true, // 保留会话
       connectTimeout: 4000, // 超时时间
       reconnectPeriod: 4000, // 重连时间间隔
       // 认证信息
       clientId: '客户端唯一ID标识', // 根据自己需要自定义
       username: '用户名', // 用户名和密码根据实际情况而定
       password: '密码',
       lastWillTopic: 'maker',
     };
      
     // 订阅主题
     const subscription = {
       topic: 'topic', // 主题
       qos: 1, // 等级
     };
    
     // 发布消息
     const publish = {
       topic: 'topic',
       qos: 1, // 等级
       payload: '{ "msg": "Hello, I am browser." }', // 需要发布的信息,格式为字符串或者Arrybuffer
     };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
  • 连接MQTT服务器

    const creatConnectFun = async () => {
      const { host, port, endpoint, ...options } = connection;
      const connectUrl = `mqtt://${host}:${port}${endpoint}`;
    
      try {
        // 连接MQTT服务器并返回客户端信息
        client = MQTT.connect(connectUrl, options);
      } catch (error) {
        console.log('mqtt.connect error', error);
      }
    
    // 客户端连接成功监听事件
      client.on('connect', () => {
        console.log('Connection succeeded!');
      });
    
    // 客户端连接失败监听事件
      client.on('error', (error: any) => {
        console.log('Connection failed', error);
      });
    
      // 客户端接收MQTT服务端发布的实时消息
      client.on('message', (topic: any, message: any) => {
        console.log('message', message);
      });
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    在这里插入图片描述
    这是连接MQTT服务器成功后返回客户端信息的对象数据

  • 断开与MQTT服务器

    const disConnectFun = async () => {
    	if (client?.connected) {
    		try {
    			 client.end();
    			 client = {};
    			 console.log('Successfully disconnected!');
    		} catch (error: any) {
    		 	console.log('Disconnect failed', error.toString());
    		}
    	}
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
  • 订阅消息

    const doSubscribe = async () => {
      const { topic, qos } = subscription;
      client.subscribe(topic, { qos }, (error: any, res: any) => {
        if (error) {
          console.log('Subscribe to topics error', error);
          return;
        }
        console.log('Subscribe to topics res', res);
      });
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
  • 发布消息

    const pubFun = async () => {
       const { topic, qos, payload } = publish;
       client.publish(topic, payload, { qos }, (error: any) => {
         if (error) {
           console.log('Publish error', error);
         } else {
           console.log('已发布的消息:', publish);
         }
       });
     };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述
    这是订阅主题及发布消息。

    注意:此处发布消息可以是字符串或者ArrayBuffer

    // 此段代码来自于MQTT源码
    public publish (topic: string, message: string | Buffer,
                  opts: IClientPublishOptions, callback?: PacketCallback): this
    public publish (topic: string, message: string | Buffer,
                  callback?: PacketCallback): this
    
    • 1
    • 2
    • 3
    • 4
    • 5

    注意:此处客户端监听到发布的消息并进行接收到的数据是ArrayBuffer格式,需要对其进行数据转换。

     client.on('message', (topic: any, message: any) => {
     	/*
    		对未加密数据而言,返回的ArrayBUffer格式数据转换为字符串即可;
    		对于已经加密的数据,则需要根据自身需求进行解密处理即可,此处不过多赘述。
    	*/
        console.log('message', message.toString());
      });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
  • 取消订阅

    const doUnSubscribe = async () => {
       const { topic } = subscription;
       client.unsubscribe(topic, (error: any) => {
         if (error) {
           console.log('Unsubscribe error', error);
         }
         console.log('Unsubscribe success');
       });
     };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

MQTT的通信质量

MQTT服务质量(Quality of Service 缩写 QoS)正是用于告知物联网系统,哪些信息是重要信息需要准确无误的传输,而哪些信息不那么重要,即使丢失也没有问题,因为很快下一次读记录就会产生。

MQTT协议有三种服务质量级别:

  • QoS = 0 – 最多发一次

    0是服务质量QoS的最低级别。当QoS为0级时,MQTT协议并不保证所有信息都能得以传输。也就是说,QoS=0的情况下,MQTT服务端和客户端不会对消息传输是否成功进行确认和检查。消息能否成功传输全看网络环境是否稳定。
    也就是说,在QoS为0时。发送端一旦发送完消息后,就完成任务了。发送端不会检查发出的消息能否被正确接收到。
    在网络环境稳定的情况下,信息传输一般是不会出现问题的。但是在环境不稳定的情况下,可能会在传输过程中出现MQTT消息丢失的情况。

  • QoS = 1 – 最少发一次

  • QoS = 2 – 保证收一次

    以上三种不同的服务质量级别意味着不同的MQTT传输流程。对于较为重要的MQTT消息,我们通常会选择QoS>0的服务级别(即QoS 为1或2)。

以上基本就是我学习MQTT以及在项目中应用的一些粗浅心得,可以说连他的冰山一角都没有碰到,因为时间有限,希望后面有时间再继续深度学习一下。

另外我再学习的过程中查看了一些前人的资料,我这里要特别感谢:太极创客 这个网站,因为有他我才学习的更加轻松自如。
这个网站对于MQTT讲解的还是比较的细致,有文章,也有视频讲解,真的是很贴心啊,另外我文章中也有引用到他们的文章段落,主要是他们的讲解描述确实是很通俗易懂。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/188584
推荐阅读
相关标签
  

闽ICP备14008679号