前端如何对接mqtt协议,接收数据?

833 阅读2分钟

背景

  1. 对不同主题的mqtt消息监听
  2. 接收到实时消息后,进行业务场景处理
  3. 根据业务场景,选择是持续监听还是组件内监听

功能实现--以vue为例

插件引入

npm i mqtt -D
or
yarn add mqtt

mqtt工具类封装

写在前面

  1. 定义USER_NAME和PASSWORD,账号和密码一般不会变,可以写成常量
  2. 定义clientId,随机生成
  3. 定义响应超时时间
  4. 编写方法,提供订阅、取消订阅、消息回调、结束连接等方法

mqtt类

import mqtt from 'mqtt/dist/mqtt.min.js'

import { generateId } from './index'

const URL = `ws://27.0.0.1:9001/`
const USE_NAME = 'userName'
const PASSWORD = 'password'
const TIMEOUT = 4000
export class UseMqtt {
  constructor(topic, url = URL, user=USE_NAME, password=PASSWORD) {
    this.url = url
    this.topic = topic
    this.user = user
    this.password = password
  }
  //初始化mqtt
  _init() {
    const options = {
      clean: true,
      clientId: generateId(20),
      username: this.user,
      password: this.password,
      connectTimeout: TIMEOUT,
    }
    this.client = mqtt.connect(this.url, options)
    this.client.on('error', (error) => {
      console.error(error)
    })
    this.client.on('reconnect', (error) => {
      console.log(error)
    })
  }
  //取消订阅
  unsubscribes() {
    this.client.unsubscribe(this.topic, (error) => {
      if ((error ?? '') === '') {
        console.log(this.topic, '取消订阅成功')
      } else {
        console.log(this.topic, '取消订阅失败')
      }
    })
  }
  //订阅
  subscribes() {
    this._init()
    this.client.on('connect', () => {
      this.client.subscribe(this.topic, (error) => {
        if (!error) {
          console.log('订阅成功')
        } else {
          console.log('error')
        }
      })
    })
  }
  //消息回调
  getMessage(callback) {
    this.client.on('message', (topic, message) => {
      return callback({ topic, message: message.toString() })
    })
  }
  //结束链接
  end() {
    this.client.end()
  }
}

generateId为生成随机数的函数,初始化方法——init用于连接mqtt,subscribes方法用于订阅主题,getMessage方法用于在订阅成功后,接收消息,unsubscribes方法用于取消订阅,end方法用于断开连接

在组件中使用

import { UseMqtt } from '@/utils/mqtt'

let mqttInstance = null;

const handleConnectMqtt = () => {
  mqttInstance = new UseMqtt('/mqtt/topic_content/#');
  mqttInstance.subscribes();
  mqttInstance.getMessage(handleMqttMessages);
}
const handleMqttMessages = async (messages) => {
  const { message, topic } = messages;
  //具体业务
}

如上述代码所示,引入封装好的mqtt工具类,定义一个变量用于接收new的实例,便于在组件内进行实例的操作,调用的步骤不复杂,首先将后端给到的topic传入实例中,调用实例的订阅方法,最后调用实例的消息回调函数,当有数据上报后,就可以监听到传来的数据,根据数据结构对数据内容进行解构,拿到需要的内容,进行业务逻辑的开发。

总结

整体上,对于mqtt连接与处理并不复杂,这里单独将mqtt的功能抽离出来,当作一个工具类,让需要用到的组件进行调用即可,减少代码的冗余的同时,也避免了与业务代码耦合度过高的问题,符合单一职责的设计思想,对于团队协同开发来说,一定程度上提高了开发的效率。

欢迎同学们批评指正!

往期精彩

# webpack5-构建速度提升篇

# 操刀Proxy & Reflect 实现一个简单的数据双向绑定,理解vue3的双向绑定原理

# vue项目使用webpack进行打包优化

# 不分框架的前端视频组件封装

# 前端打包发布一条龙--SCP2

# 使用speechSynthesis实现文字转语音功能