封装mqtt.js实现websocket连接

/**
 * Created by SongPeng on 2019-5-31
 */
import { Dialog } from 'vant'
import mqtt from 'mqtt'
// import tools from './tools'
import common from './common'
import store from '@/store/index'
// import router from '@/router/index'
import { getEquiKey } from '@/api/device'
let [loading, vm, timer1] = [{}, {}, null]
const mqttClient = {
  ws: {},
  pramas: {},
  initMqtt (options) {
    this.pramas = Object.assign({
      port: 8083,
      keepalive: 60,
      clientId: options.id,
      clean: true,
      username: '',
      password: '',
      path: '/mqtt'
    }, options)
    this.ws = mqtt('mqtt://47.105.162.0', this.pramas)
    this.ws.on('connect', (e) => {
      // if (Reflect.has(Dialog, 'close'))Dialog.close()
      // console.log(`${this.pramas.clientId}连接成功`)
      if (!store.state.mqttOnline) store.commit('CHANGEMQTTSTATE', !0)
    })
    this.ws.on('error', (e) => {
      // console.log('error', e)
    })
    this.ws.on('offline', (e) => {
      if (store.state.mqttOnline) store.commit('CHANGEMQTTSTATE', !1)
      // Dialog.alert({
      //   title: '提示',
      //   message: 'mqtt服务已掉线,请检测网络后等待重连或者刷新后重试',
      //   showCancelButton: !0
      // })
      // console.log('offline', e)
    })
    this.ws.on('disconnect', (e) => {
      // console.log('disconnect', e)
    })
    this.ws.on('close', (e) => {
      // console.log('close', e)
    })
    this.ws.on('message', (topic, payload) => {
      console.log('%c收到message,解密前原始数据', 'color:#0088f5', payload)
      if (Reflect.has(loading, 'clear')) {
        loading.clear()
        clearInterval(timer1)
      }
      if (Reflect.has(Dialog, 'close'))Dialog.close()
      // clearTimeout(timer)
      let data = common.decryptedData(payload)
      // console.log('%c解密完成数据:', 'color:#0088f5;', data)
      if (data.index === window.$index) {
        window.$index++
        vm.onMqttMessage(topic, data)
      } else {
        // to do something
        // console.log('index对应', window.$index + '!==' + data.index)
      }
    })
  },
  checkState (success = function () { }) {
    this.ws.on('connect', (e) => {
      // console.log(`${this.pramas.clientId}连接成功`)
      success(e)
    })
  },
  /**
   * 自定义mqtt publish (9)
   * @param {Object} data 总数据
   * @param {Object} data._this vue实例
   * @param {String} data.topic topic
   * @param {Array} data.encryptedData 加密数据
   * @param {Object} data.message 展示信息
   * @param {Object} data.showInterval 展示定义器
   * @param {Object} data.showFailTip 展示错误提示
   * @param {Object} data.DialogOptions Dialog参数
   * @param {Object} data.options mqtt publish options
   * @param {Object} data.timeOut 超时时间
   */
  publish (data) {
    return new Promise((resolve, reject) => {
      data = Object.assign({
        _this: data._this,
        topic: '',
        encryptedData: [],
        message: '连接中',
        showInterval: !0,
        showFailTip: !0,
        DialogOptions: {
          title: '提示',
          message: '与设备连接超时',
          confirmButtonText: '确认'
        },
        options: {},
        timeOut: 10
      }, data)
      if (data._this === null) console.error('[data._this] can not be null, you should check if send vue[this]?')
      if (data.topic === '') console.error('[publish.topic] can not be undefined')
      vm = data._this
      if (data.showInterval) {
        loading = common.showIntervalLoading({
          message: `${data.message}10秒`
        })
        let second = data.timeOut
        clearInterval(timer1)
        timer1 = setInterval(() => {
          second--
          if (second) {
            loading.message = `${data.message}${second}秒`
          } else {
            clearInterval(timer1)
            loading.clear()
            if (data.showFailTip) {
              loading.clear()
              Dialog.alert(data.DialogOptions)
            }
            resolve(data.topic)
          }
        }, 1000)
      }
      console.log('发送数据:', new Uint8Array(data.encryptedData))
      this.ws.publish(data.topic, new Uint8Array(data.encryptedData), Object.assign({ qos: 0 }, data.options), (err) => {
        if (err) {
          // console.log(err)
          loading.clear()
          clearInterval(timer1)
          Dialog.alert({
            title: '提示',
            message: '发送信息失败'
          })
        } else {
          console.log('%c数据发送成功', 'color:#ea3800')
        }
      })
    })
  },
  end () {
    this.ws.end()
  },
  destroy () {
    clearInterval(timer1)
    loading.clear()
    Dialog.close()
  },
  subscribe (topic, options, callback = function () { }) {
    this.ws.subscribe(topic, Object.assign({ qos: 0 }, options), (err) => {
      if (err) {
        Dialog.alert({
          title: '提示',
          message: '订阅失败'
        })
      }
      callback(err)
    })
  },
  unsubscribe (topic, options, callback = function () { }) {
    this.ws.unsubscribe(topic, Object.assign({ qos: 0 }, options), (err) => {
      if (!err) {
        callback()
      }
    })
  },
  /**
   * 自定义mqtt sendMessage (11)
   * @param {Object} t 总数据
   * @param {Object} t._this vue实例
   * @param {Array} t.data 加密前数据
   * @param {String} t.equiImei 设备Imei
   * @param {Boolean} t.showInterval 展示定时器
   * @param {Boolean} t.showFailTip 展示错误提示
   * @param {String} t.message 信息提示
   * @param {Object} t.subscribePrefix sub前缀
   * @param {Object} t.publishPrefix pub前缀
   * @param {Object} t.DialogOptions Dialog参数
   * @param {Object} t.options mqtt publish options
   * @param {Object} t.timeOut 超时时间
   */
  sendMessage (t) {
    return new Promise((resolve, reject) => {
      t = Object.assign({
        _this: null,
        data: [],
        equiImei: '',
        showInterval: !0,
        showFailTip: !0,
        message: '同步中',
        subscribePrefix: '2/5',
        publishPrefix: '2/3',
        DialogOptions: {
          title: '提示',
          message: '与设备连接超时',
          confirmButtonText: '确认'
        },
        options: {},
        timeOut: 10
      }, t)
      this.subscribe(`${t.subscribePrefix}/${t.equiImei}`, {}, (err) => {
        if (!err) {
          getEquiKey({
            equiImei: t.equiImei
          })
            .then(res => {
              if (res.code === 0) {
                this.publish({
                  _this: t._this,
                  topic: `${t.publishPrefix}/${t.equiImei}`,
                  encryptedData: common.getEncryptedData(t.cmdType, [...t.data], res.data),
                  options: t.options,
                  showInterval: t.showInterval,
                  message: t.message,
                  showFailTip: t.showFailTip,
                  DialogOptions: t.DialogOptions,
                  timeOut: t.timeOut
                })
                  .then(res => {
                    console.log('数据获取失败')
                    resolve(res)
                  })
              }
            })
        }
      })
    })
  }
}
export default mqttClient

tools.js

/**
 * Created by SongPeng on 2019-5-31
 */
export default {
  /**
   * 十六进制字符串转字节数组
   * 每2个字符串转换
   * 100102030405060708 转为 [16, 1, 2, 3, 4, 5, 6, 7, 8]
   * @param {String} str 符合16进制字符串
   */
  Str2Bytes (str) {
    console.log(str)
    var pos = 0
    var len = str.length
    if (len % 2 !== 0) {
      return null
    }
    len /= 2
    var hexA = []
    for (var i = 0; i < len; i++) {
      var s = str.substr(pos, 2)
      var v = parseInt(s, 16)
      hexA.push(v)
      pos += 2
    }
    return hexA
  },
  /**
   * 字节数组转十六进制字符串
   * [16, 1, 2, 3, 4, 5, 6, 7, 8] 转换 100102030405060708
   * @param {Array} arr 符合16进制数组
   */
  Bytes2Str (arr) {
    var str = ''
    for (var i = 0; i < arr.length; i++) {
      var tmp = arr[i].toString(16)
      if (tmp.length === 1) {
        tmp = '' + tmp
      }
      str += tmp
    }
    return str
  },
  /**
   * 数组进行异或
   * @param {Array} arr 数组
   */
  BytesDes (arr) {
    var des = arr[0]
    for (var i = 1; i < arr.length; i++) {
      des ^= arr[i]
    }
    return des
  },
  /**
   * 十六进制数组转十进制数组
   * @param {Array} arr 十六进制数组
   */
  Array16to10 (arr) {
    var list = []
    arr.forEach(element => {
      list = [
        ...list,
        ...this.Str2Bytes(element)
      ]
    })
    return list
  },
  /**
   * 十进制数组转十六进制数组
   * @param {Array} arr 十进制数组
   */
  Array10to16 (arr) {
    var list = []
    arr.forEach(element => {
      list[list.length] = this.toHex(element)
    })
    return list
  },
  /**
   * 十进制转十六进制
   * 15 转 0F
   * @param {Number} num 十进制数字
   */
  toHex (num) {
    if (num <= 255) {
      return ('0' + (Number(num).toString(16))).slice(-2).toUpperCase()
    } else {
      var str = num.toString(16)
      if (str.length === 3) {
        return '0' + str
      } else {
        return str
      }
    }
  },
  /**
   * byte数组 转 int
   * @param {Array} arr
   */
  byteToInt (arr) {
    let [all, int] = ['', 0]
    arr.forEach(value => {
      value = value.toString(2)
      if (value.length < 8) {
        for (let i = 0; i < 10; i++) {
          value = '0' + value
          if (value.length === 8) {
            i = 10
          }
        }
      }
      all = all + value
    })
    for (let o = 0; o < all.length; o++) {
      int = int + +all[o] * Math.pow(2, all.length - o - 1)
    }
    return int
  },
  /**
   * int 转 两位byte数组
   * @param {Array} arr
   */
  intToTwoByte (int) {
    let arr = []
    if (int <= 255) {
      arr = [0, int]
    } else {
      arr = this.Str2Bytes(this.toHex(int))
    }
    return arr
  }
}

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: MQTT.js 是一个用于 JavaScript 的用于实现 MQTT 协议的客户端库。MQTT 是一种轻量级的发布/订阅消息传输协议,可以在低带宽、不稳定网络条件下进行高效的通信。 Websocket 是一种全双工通信协议,允许在 Web 浏览器和服务器之间进行实时数据传输。与传统的 HTTP 请求-响应机制不同,Websocket 可以在浏览器和服务器之间建立长久的连接实现双向通信,从而可以实时更新数据而无需进行多次的请求和响应过程。 MQTT.js WebSocket 是基于 MQTT.js 库使用 Websocket 进行通信的一种方式。通过使用 MQTT.js WebSocket,我们可以在浏览器中实现 MQTT 协议的功能,从而能够在 Web 应用程序中进行实时消息传输和订阅。 使用 MQTT.js WebSocket,我们可以轻松地在浏览器中创建 MQTT 客户端,与 MQTT 服务器进行连接,并通过订阅和发布主题来实现实时消息的传输。这样,我们可以实现各种场景下的实时数据传输,如物联网设备之间的通信、实时监控系统等。 总结来说,MQTT.js WebSocket 是一种用于在浏览器中实现 MQTT 协议的客户端库,提供了与 MQTT 服务器进行实时消息传输的功能。使用它,我们可以实现实时消息的订阅和发布,为各种实时数据传输场景提供便利。 ### 回答2: MQTT.js是一个基于JavaScript的客户端库,用于实现MQTT协议的通信。它为Web浏览器和Node.js提供了一个简单的接口,以便实现MQTT代理的通信。 WebSocket是一种通信协议,它提供了双向的、实时的数据传输能力。MQTT.js通过WebSocket实现MQTT代理的通信,使得基于浏览器和Node.js的应用程序能够与MQTT代理进行实时的数据交互。 使用MQTT.js WebSocket的时候,首先需要在应用程序中引入MQTT.js库,并创建一个MQTT客户端实例。然后,通过指定WebSocket的URL和端口号,将MQTT客户端与MQTT代理进行连接连接成功后,就可以使用MQTT.js的API来发布消息或订阅主题了。 MQTT.js WebSocket的优点是它能够在浏览器和Node.js环境下进行跨平台的通信。同时,它也支持多种认证机制和可定制化的选项,以及保持长连接和断线重连的功能。此外,MQTT.jsMQTT代理之间的通信是基于二进制协议的,所以效率较高。 总结起来,MQTT.js WebSocket提供了一种便捷的方式,使得浏览器和Node.js应用程序能够通过MQTT协议与MQTT代理进行实时的双向数据交互。 ### 回答3: MQTT.js 是一个基于 JavaScript 的 MQTT 客户端库,用于在浏览器或 Node.js 环境中使用 MQTT 协议进行消息传输。 WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议,允许客户端和服务器之间实时地进行双向通信。 MQTT.js 通过使用 WebSocket 协议来提供浏览器中的 MQTT 客户端功能。它允许在浏览器中使用 MQTT 协议进行消息传输,实现实时数据传递。 使用 MQTT.js WebSocket,可以通过创建一个 MQTT 客户端实例来连接MQTT 代理服务器。通过这个客户端实例,可以订阅和发布消息,并与其他 MQTT 客户端进行实时通信。 MQTT.js WebSocket 具有以下特点: 1. 简单易用:MQTT.js 提供了简单的 API 来连接MQTT 代理服务器,订阅和发布消息。 2. 兼容性:MQTT.js 能够在浏览器和 Node.js 环境中运行,具有较好的兼容性。 3. 实时性:通过使用 WebSocket 协议,MQTT.js 实现了客户端和服务器之间的实时双向通信,可以实时传递数据。 4. 轻量级:MQTT 协议本身是一种轻量级的消息传输协议,而 MQTT.js 使用 WebSocket实现 MQTT 功能,保持了协议的轻量级特性。 总之,MQTT.js WebSocket 提供了一种方便、快捷的方式来在浏览器或 Node.js 环境中使用 MQTT 协议进行实时消息传输。无论是在物联网设备间的通信,还是在实时数据传递的场景中,都可以使用 MQTT.js WebSocket实现高效的消息传输。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值